1
0
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:
Nicky Gerritsen 2015-10-27 13:46:05 -04:00 committed by Gary Katsevman
parent c85b526a1c
commit 589cab7fa7
11 changed files with 178 additions and 19 deletions

View File

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

View File

@ -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
*

View File

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

View File

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

View File

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

View File

@ -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'

View File

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

View File

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

View File

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

View File

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

View File

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