mirror of
https://github.com/videojs/video.js.git
synced 2024-12-25 02:42:10 +02:00
@nickygerritsen added canPlayType method to player. closes #2709
This commit is contained in:
parent
c85b526a1c
commit
589cab7fa7
@ -6,6 +6,7 @@ CHANGELOG
|
||||
* @gkatsev removed unhelpful isCrossOrigin test ([view](https://github.com/videojs/video.js/pull/2715))
|
||||
* @forbesjo updated karma to use all installed browsers for unit tests ([view](https://github.com/videojs/video.js/pull/2708))
|
||||
* @forbesjo removed android/ios tests to increase build stability ([view](https://github.com/videojs/video.js/pull/2739))
|
||||
* @nickygerritsen added canPlayType method to player ([view](https://github.com/videojs/video.js/pull/2709))
|
||||
|
||||
--------------------
|
||||
|
||||
|
@ -1639,6 +1639,40 @@ class Player extends Component {
|
||||
this.trigger('exitFullWindow');
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the player can play a given mimetype
|
||||
*
|
||||
* @param {String} type The mimetype to check
|
||||
* @return {String} 'probably', 'maybe', or '' (empty string)
|
||||
* @method canPlayType
|
||||
*/
|
||||
canPlayType(type) {
|
||||
let can;
|
||||
|
||||
// Loop through each playback technology in the options order
|
||||
for (let i = 0, j = this.options_.techOrder; i < j.length; i++) {
|
||||
let techName = toTitleCase(j[i]);
|
||||
let tech = Component.getComponent(techName);
|
||||
|
||||
// Check if the current tech is defined before continuing
|
||||
if (!tech) {
|
||||
log.error(`The "${techName}" tech is undefined. Skipped browser support check for that tech.`);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check if the browser supports this technology
|
||||
if (tech.isSupported()) {
|
||||
can = tech.canPlayType(type);
|
||||
|
||||
if (can) {
|
||||
return can;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Select source based on tech order
|
||||
*
|
||||
|
@ -60,12 +60,31 @@ function FlashRtmpDecorator(Flash) {
|
||||
Flash.rtmpSourceHandler = {};
|
||||
|
||||
/**
|
||||
* Check Flash can handle the source natively
|
||||
* Check if Flash can play the given videotype
|
||||
* @param {String} type The mimetype to check
|
||||
* @return {String} 'probably', 'maybe', or '' (empty string)
|
||||
*/
|
||||
Flash.rtmpSourceHandler.canPlayType = function(type){
|
||||
if (Flash.isStreamingType(type)) {
|
||||
return 'maybe';
|
||||
}
|
||||
|
||||
return '';
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if Flash can handle the source natively
|
||||
* @param {Object} source The source object
|
||||
* @return {String} 'probably', 'maybe', or '' (empty string)
|
||||
*/
|
||||
Flash.rtmpSourceHandler.canHandleSource = function(source){
|
||||
if (Flash.isStreamingType(source.type) || Flash.isStreamingSrc(source.src)) {
|
||||
let can = Flash.rtmpSourceHandler.canPlayType(source.type);
|
||||
|
||||
if (can) {
|
||||
return can;
|
||||
}
|
||||
|
||||
if (Flash.isStreamingSrc(source.src)) {
|
||||
return 'maybe';
|
||||
}
|
||||
|
||||
|
@ -352,6 +352,19 @@ Tech.withSourceHandlers(Flash);
|
||||
*/
|
||||
Flash.nativeSourceHandler = {};
|
||||
|
||||
/**
|
||||
* Check if Flash can play the given videotype
|
||||
* @param {String} type The mimetype to check
|
||||
* @return {String} 'probably', 'maybe', or '' (empty string)
|
||||
*/
|
||||
Flash.nativeSourceHandler.canPlayType = function(type){
|
||||
if (type in Flash.formats) {
|
||||
return 'maybe';
|
||||
}
|
||||
|
||||
return '';
|
||||
};
|
||||
|
||||
/*
|
||||
* Check Flash can handle the source natively
|
||||
*
|
||||
@ -376,11 +389,7 @@ Flash.nativeSourceHandler.canHandleSource = function(source){
|
||||
type = source.type.replace(/;.*/, '').toLowerCase();
|
||||
}
|
||||
|
||||
if (type in Flash.formats) {
|
||||
return 'maybe';
|
||||
}
|
||||
|
||||
return '';
|
||||
return Flash.nativeSourceHandler.canPlayType(type);
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -828,6 +828,22 @@ Tech.withSourceHandlers(Html5);
|
||||
*/
|
||||
Html5.nativeSourceHandler = {};
|
||||
|
||||
/*
|
||||
* Check if the video element can play the given videotype
|
||||
*
|
||||
* @param {String} type The mimetype to check
|
||||
* @return {String} 'probably', 'maybe', or '' (empty string)
|
||||
*/
|
||||
Html5.nativeSourceHandler.canPlayType = function(type){
|
||||
// IE9 on Windows 7 without MediaPlayer throws an error here
|
||||
// https://github.com/videojs/video.js/issues/519
|
||||
try {
|
||||
return Html5.TEST_VID.canPlayType(type);
|
||||
} catch(e) {
|
||||
return '';
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* Check if the video element can handle the source natively
|
||||
*
|
||||
@ -837,24 +853,14 @@ Html5.nativeSourceHandler = {};
|
||||
Html5.nativeSourceHandler.canHandleSource = function(source){
|
||||
var match, ext;
|
||||
|
||||
function canPlayType(type){
|
||||
// IE9 on Windows 7 without MediaPlayer throws an error here
|
||||
// https://github.com/videojs/video.js/issues/519
|
||||
try {
|
||||
return Html5.TEST_VID.canPlayType(type);
|
||||
} catch(e) {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
// If a type was provided we should rely on that
|
||||
if (source.type) {
|
||||
return canPlayType(source.type);
|
||||
return Html5.nativeSourceHandler.canPlayType(source.type);
|
||||
} else if (source.src) {
|
||||
// If no type, fall back to checking 'video/[EXTENSION]'
|
||||
ext = Url.getFileExtension(source.src);
|
||||
|
||||
return canPlayType(`video/${ext}`);
|
||||
return Html5.nativeSourceHandler.canPlayType(`video/${ext}`);
|
||||
}
|
||||
|
||||
return '';
|
||||
|
@ -424,6 +424,19 @@ class Tech extends Component {
|
||||
*/
|
||||
setPoster() {}
|
||||
|
||||
/*
|
||||
* Check if the tech can support the given type
|
||||
*
|
||||
* The base tech does not support any type, but source handlers might
|
||||
* overwrite this.
|
||||
*
|
||||
* @param {String} type The mimetype to check
|
||||
* @return {String} 'probably', 'maybe', or '' (empty string)
|
||||
*/
|
||||
canPlayType() {
|
||||
return '';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
@ -498,6 +511,26 @@ Tech.withSourceHandlers = function(_Tech){
|
||||
handlers.splice(index, 0, handler);
|
||||
};
|
||||
|
||||
/*
|
||||
* Check if the tech can support the given type
|
||||
* @param {String} type The mimetype to check
|
||||
* @return {String} 'probably', 'maybe', or '' (empty string)
|
||||
*/
|
||||
_Tech.canPlayType = function(type){
|
||||
let handlers = _Tech.sourceHandlers || [];
|
||||
let can;
|
||||
|
||||
for (let i = 0; i < handlers.length; i++) {
|
||||
can = handlers[i].canPlayType(type);
|
||||
|
||||
if (can) {
|
||||
return can;
|
||||
}
|
||||
}
|
||||
|
||||
return '';
|
||||
};
|
||||
|
||||
/*
|
||||
* Return the first source handler that supports the source
|
||||
* TODO: Answer question: should 'probably' be prioritized over 'maybe'
|
||||
|
@ -824,3 +824,12 @@ expect(3);
|
||||
player.language('en-GB');
|
||||
strictEqual(player.localize('Good'), 'Brilliant', 'Ignored case');
|
||||
});
|
||||
|
||||
test('should return correct values for canPlayType', function(){
|
||||
var player = TestHelpers.makePlayer();
|
||||
|
||||
equal(player.canPlayType('video/mp4'), 'maybe', 'player can play mp4 files');
|
||||
equal(player.canPlayType('video/unsupported-format'), '', 'player can not play unsupported files');
|
||||
|
||||
player.dispose();
|
||||
});
|
||||
|
@ -135,6 +135,16 @@ test('should have the source handler interface', function() {
|
||||
ok(Flash.registerSourceHandler, 'has the registerSourceHandler function');
|
||||
});
|
||||
|
||||
test('canPlayType should select the correct types to play', function () {
|
||||
let canPlayType = Flash.nativeSourceHandler.canPlayType;
|
||||
|
||||
equal(canPlayType('video/flv'), 'maybe', 'should be able to play FLV files');
|
||||
equal(canPlayType('video/x-flv'), 'maybe', 'should be able to play x-FLV files');
|
||||
equal(canPlayType('video/mp4'), 'maybe', 'should be able to play MP4 files');
|
||||
equal(canPlayType('video/m4v'), 'maybe', 'should be able to play M4V files');
|
||||
equal(canPlayType('video/ogg'), '', 'should return empty string if it can not play the video');
|
||||
});
|
||||
|
||||
test('canHandleSource should be able to work with src objects without a type', function () {
|
||||
let canHandleSource = Flash.nativeSourceHandler.canHandleSource;
|
||||
|
||||
|
@ -155,6 +155,27 @@ test('should have the source handler interface', function() {
|
||||
ok(Html5.registerSourceHandler, 'has the registerSourceHandler function');
|
||||
});
|
||||
|
||||
test('native source handler canPlayType', function(){
|
||||
var result;
|
||||
|
||||
// Stub the test video canPlayType (used in canPlayType) to control results
|
||||
var origCPT = Html5.TEST_VID.canPlayType;
|
||||
Html5.TEST_VID.canPlayType = function(type){
|
||||
if (type === 'video/mp4') {
|
||||
return 'maybe';
|
||||
}
|
||||
return '';
|
||||
};
|
||||
|
||||
var canPlayType = Html5.nativeSourceHandler.canPlayType;
|
||||
|
||||
equal(canPlayType('video/mp4'), 'maybe', 'Native source handler reported type support');
|
||||
equal(canPlayType('foo'), '', 'Native source handler handled bad type');
|
||||
|
||||
// Reset test video canPlayType
|
||||
Html5.TEST_VID.canPlayType = origCPT;
|
||||
});
|
||||
|
||||
test('native source handler canHandleSource', function(){
|
||||
var result;
|
||||
|
||||
|
@ -50,6 +50,7 @@ class TechFaker extends Tech {
|
||||
|
||||
// Support everything except for "video/unsupported-format"
|
||||
static isSupported() { return true; }
|
||||
static canPlayType(type) { return (type !== 'video/unsupported-format' ? 'maybe' : ''); }
|
||||
static canPlaySource(srcObj) { return srcObj.type !== 'video/unsupported-format'; }
|
||||
}
|
||||
|
||||
|
@ -132,6 +132,12 @@ test('should add the source handler interface to a tech', function(){
|
||||
|
||||
// Create source handlers
|
||||
var handlerOne = {
|
||||
canPlayType: function(type){
|
||||
if (type !=='no-support') {
|
||||
return 'probably';
|
||||
}
|
||||
return '';
|
||||
},
|
||||
canHandleSource: function(source){
|
||||
if (source.type !=='no-support') {
|
||||
return 'probably';
|
||||
@ -146,6 +152,9 @@ test('should add the source handler interface to a tech', function(){
|
||||
};
|
||||
|
||||
var handlerTwo = {
|
||||
canPlayType: function(type){
|
||||
return ''; // no support
|
||||
},
|
||||
canHandleSource: function(source){
|
||||
return ''; // no support
|
||||
},
|
||||
@ -164,6 +173,10 @@ test('should add the source handler interface to a tech', function(){
|
||||
strictEqual(MyTech.selectSourceHandler(sourceA), handlerOne, 'handlerOne was selected to handle the valid source');
|
||||
strictEqual(MyTech.selectSourceHandler(sourceB), null, 'no handler was selected to handle the invalid source');
|
||||
|
||||
// Test canPlayType return values
|
||||
strictEqual(MyTech.canPlayType(sourceA.type), 'probably', 'the Tech returned probably for the valid source');
|
||||
strictEqual(MyTech.canPlayType(sourceB.type), '', 'the Tech returned an empty string for the invalid source');
|
||||
|
||||
// Test canPlaySource return values
|
||||
strictEqual(MyTech.canPlaySource(sourceA), 'probably', 'the Tech returned probably for the valid source');
|
||||
strictEqual(MyTech.canPlaySource(sourceB), '', 'the Tech returned an empty string for the invalid source');
|
||||
@ -239,6 +252,9 @@ test('delegates seekable to the source handler', function(){
|
||||
};
|
||||
|
||||
MyTech.registerSourceHandler({
|
||||
canPlayType: function() {
|
||||
return true;
|
||||
},
|
||||
canHandleSource: function() {
|
||||
return true;
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user