mirror of
https://github.com/jellyfin/jellyfin-web
synced 2025-03-30 19:56:21 +00:00
Add and fix some canPlayType
This commit is contained in:
parent
baad6dc4b0
commit
f647a1b4c3
1 changed files with 103 additions and 64 deletions
|
@ -5,8 +5,8 @@ define(['browser'], function (browser) {
|
||||||
return !!(videoTestElement.canPlayType && videoTestElement.canPlayType('video/mp4; codecs="avc1.42E01E, mp4a.40.2"').replace(/no/, ''));
|
return !!(videoTestElement.canPlayType && videoTestElement.canPlayType('video/mp4; codecs="avc1.42E01E, mp4a.40.2"').replace(/no/, ''));
|
||||||
}
|
}
|
||||||
|
|
||||||
function canPlayH265(videoTestElement, options) {
|
function canPlayH265(videoTestElement, protocol) {
|
||||||
if (browser.tizen || browser.orsay || browser.xboxOne || browser.web0s || options.supportsHevc) {
|
if (browser.tizen || browser.orsay || browser.xboxOne || browser.web0s) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,12 +18,27 @@ define(['browser'], function (browser) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unfortunately haven't yet found a canPlayType for proper detection
|
if (browser.ps4) {
|
||||||
if (browser.iOS && (browser.iOSVersion || 0) >= 11) {
|
return false;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return !!(videoTestElement.canPlayType && videoTestElement.canPlayType('video/hevc; codecs="hevc, aac"').replace(/no/, ''));
|
if (protocol === 'hls') {
|
||||||
|
|
||||||
|
//safari seems to be lying about this
|
||||||
|
if (browser.iOS || browser.safari) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return !!videoTestElement.canPlayType &&
|
||||||
|
(videoTestElement.canPlayType('video/mp2t; codecs="hvc1.1.L0.0"').replace(/no/, '') ||
|
||||||
|
videoTestElement.canPlayType('video/mp2t; codecs="hev1.1.L0.0"').replace(/no/, '') ||
|
||||||
|
videoTestElement.canPlayType('video/mp2t; codecs="hev1.1.2.L150"').replace(/no/, ''));
|
||||||
|
}
|
||||||
|
|
||||||
|
return !!videoTestElement.canPlayType &&
|
||||||
|
(videoTestElement.canPlayType('video/mp4; codecs="hvc1.1.L0.0"').replace(/no/, '') ||
|
||||||
|
videoTestElement.canPlayType('video/mp4; codecs="hev1.1.L0.0"').replace(/no/, '') ||
|
||||||
|
videoTestElement.canPlayType('video/mp4; codecs="hev1.1.2.L150"').replace(/no/, ''));
|
||||||
}
|
}
|
||||||
|
|
||||||
var _supportsTextTracks;
|
var _supportsTextTracks;
|
||||||
|
@ -41,7 +56,7 @@ define(['browser'], function (browser) {
|
||||||
}
|
}
|
||||||
|
|
||||||
var _canPlayHls;
|
var _canPlayHls;
|
||||||
function canPlayHls(src) {
|
function canPlayHls() {
|
||||||
if (_canPlayHls == null) {
|
if (_canPlayHls == null) {
|
||||||
_canPlayHls = canPlayNativeHls() || canPlayHlsWithMSE();
|
_canPlayHls = canPlayNativeHls() || canPlayHlsWithMSE();
|
||||||
}
|
}
|
||||||
|
@ -64,12 +79,8 @@ define(['browser'], function (browser) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function canPlayHlsWithMSE() {
|
function canPlayHlsWithMSE() {
|
||||||
if (window.MediaSource != null) {
|
|
||||||
// text tracks don’t work with this in firefox
|
// text tracks don’t work with this in firefox
|
||||||
return true;
|
return null != window.MediaSource;
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function supportsAc3(videoTestElement) {
|
function supportsAc3(videoTestElement) {
|
||||||
|
@ -77,11 +88,20 @@ define(['browser'], function (browser) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (browser.osx || browser.iOS) {
|
return videoTestElement.canPlayType('audio/mp4; codecs="ac-3"').replace(/no/, '');
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return videoTestElement.canPlayType('audio/mp4; codecs="ac-3"').replace(/no/, '');
|
function supportsAc3InHls(videoTestElement) {
|
||||||
|
if (browser.tizen || browser.orsay || browser.web0s) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!!videoTestElement.canPlayType) {
|
||||||
|
return videoTestElement.canPlayType('application/x-mpegurl; codecs="avc1.42E01E, ac-3"').replace(/no/, '') ||
|
||||||
|
videoTestElement.canPlayType('application/vnd.apple.mpegURL; codecs="avc1.42E01E, ac-3"').replace(/no/, '');
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function supportsEac3(videoTestElement) {
|
function supportsEac3(videoTestElement) {
|
||||||
|
@ -96,28 +116,30 @@ define(['browser'], function (browser) {
|
||||||
var typeString;
|
var typeString;
|
||||||
|
|
||||||
if (format === 'flac') {
|
if (format === 'flac') {
|
||||||
if (browser.tizen || browser.orsay || browser.web0s) {
|
if (browser.tizen || browser.orsay || browser.web0s || browser.edgeUwp) {
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (browser.edgeUwp) {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} else if (format === 'wma') {
|
} else if (format === 'wma') {
|
||||||
if (browser.tizen || browser.orsay) {
|
if (browser.tizen || browser.orsay || browser.edgeUwp) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (browser.edgeUwp) {
|
} else if (format === 'asf') {
|
||||||
|
if (browser.tizen || browser.edgeUwp) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} else if (format === 'opus') {
|
} else if (format === 'opus') {
|
||||||
|
if (!browser.web0s) {
|
||||||
typeString = 'audio/ogg; codecs="opus"';
|
typeString = 'audio/ogg; codecs="opus"';
|
||||||
if (document.createElement('audio').canPlayType(typeString).replace(/no/, '')) {
|
return !!document.createElement('audio').canPlayType(typeString).replace(/no/, '');
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
} else if (format === 'alac') {
|
||||||
|
if (browser.iOS || browser.osx) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
} else if (format === 'mp2') {
|
} else if (format === 'mp2') {
|
||||||
// For now
|
//For now
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,11 +151,7 @@ define(['browser'], function (browser) {
|
||||||
typeString = 'audio/' + format;
|
typeString = 'audio/' + format;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (document.createElement('audio').canPlayType(typeString).replace(/no/, '')) {
|
return !!document.createElement('audio').canPlayType(typeString).replace(/no/, '');
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function testCanPlayMkv(videoTestElement) {
|
function testCanPlayMkv(videoTestElement) {
|
||||||
|
@ -146,8 +164,6 @@ define(['browser'], function (browser) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
var userAgent = navigator.userAgent.toLowerCase();
|
|
||||||
|
|
||||||
// Unfortunately there's no real way to detect mkv support
|
// Unfortunately there's no real way to detect mkv support
|
||||||
if (browser.chrome) {
|
if (browser.chrome) {
|
||||||
// Not supported on opera tv
|
// Not supported on opera tv
|
||||||
|
@ -155,6 +171,8 @@ define(['browser'], function (browser) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var userAgent = navigator.userAgent.toLowerCase();
|
||||||
|
|
||||||
// Filter out browsers based on chromium that don't support mkv
|
// Filter out browsers based on chromium that don't support mkv
|
||||||
if (userAgent.indexOf('vivaldi') !== -1 || userAgent.indexOf('opera') !== -1) {
|
if (userAgent.indexOf('vivaldi') !== -1 || userAgent.indexOf('opera') !== -1) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -163,10 +181,6 @@ define(['browser'], function (browser) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (browser.edgeUwp) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -203,15 +217,15 @@ define(['browser'], function (browser) {
|
||||||
|
|
||||||
switch (container) {
|
switch (container) {
|
||||||
case 'asf':
|
case 'asf':
|
||||||
supported = browser.tizen || browser.orsay || browser.edgeUwp;
|
supported = browser.tizen || browser.orsay || browser.web0s || browser.edgeUwp;
|
||||||
videoAudioCodecs = [];
|
videoAudioCodecs = [];
|
||||||
break;
|
break;
|
||||||
case 'avi':
|
case 'avi':
|
||||||
supported = browser.tizen || browser.orsay || browser.edgeUwp;
|
supported = browser.tizen || browser.orsay || browser.web0s || browser.edgeUwp;
|
||||||
break;
|
break;
|
||||||
case 'mpg':
|
case 'mpg':
|
||||||
case 'mpeg':
|
case 'mpeg':
|
||||||
supported = browser.edgeUwp || browser.tizen || browser.orsay;
|
supported = browser.tizen || browser.orsay || browser.web0s || browser.edgeUwp;
|
||||||
break;
|
break;
|
||||||
case 'flv':
|
case 'flv':
|
||||||
supported = browser.tizen || browser.orsay;
|
supported = browser.tizen || browser.orsay;
|
||||||
|
@ -227,7 +241,7 @@ define(['browser'], function (browser) {
|
||||||
supported = browser.tizen || browser.orsay;
|
supported = browser.tizen || browser.orsay;
|
||||||
break;
|
break;
|
||||||
case 'mov':
|
case 'mov':
|
||||||
supported = browser.tizen || browser.orsay || browser.chrome || browser.edgeUwp;
|
supported = browser.tizen || browser.orsay || browser.web0s || browser.edgeUwp;
|
||||||
videoCodecs.push('h264');
|
videoCodecs.push('h264');
|
||||||
break;
|
break;
|
||||||
case 'm2ts':
|
case 'm2ts':
|
||||||
|
@ -247,7 +261,7 @@ define(['browser'], function (browser) {
|
||||||
case 'ts':
|
case 'ts':
|
||||||
supported = testCanPlayTs();
|
supported = testCanPlayTs();
|
||||||
videoCodecs.push('h264');
|
videoCodecs.push('h264');
|
||||||
if (canPlayH265(videoTestElement, options)) {
|
if (canPlayH265(videoTestElement)) {
|
||||||
videoCodecs.push('h265');
|
videoCodecs.push('h265');
|
||||||
videoCodecs.push('hevc');
|
videoCodecs.push('hevc');
|
||||||
}
|
}
|
||||||
|
@ -263,16 +277,12 @@ define(['browser'], function (browser) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!supported) {
|
return supported ? {
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
Container: profileContainer,
|
Container: profileContainer,
|
||||||
Type: 'Video',
|
Type: 'Video',
|
||||||
VideoCodec: videoCodecs.join(','),
|
VideoCodec: videoCodecs.join(','),
|
||||||
AudioCodec: videoAudioCodecs.join(',')
|
AudioCodec: videoAudioCodecs.join(',')
|
||||||
};
|
} : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getMaxBitrate() {
|
function getMaxBitrate() {
|
||||||
|
@ -373,8 +383,7 @@ define(['browser'], function (browser) {
|
||||||
|
|
||||||
// This works in edge desktop, but not mobile
|
// This works in edge desktop, but not mobile
|
||||||
// TODO: Retest this on mobile
|
// TODO: Retest this on mobile
|
||||||
var supportsAc3InHls = (!browser.edge || !browser.touch || browser.edgeUwp);
|
if (supportsAc3InHls(videoTestElement)) {
|
||||||
if (supportsAc3InHls) {
|
|
||||||
hlsVideoAudioCodecs.push('ac3');
|
hlsVideoAudioCodecs.push('ac3');
|
||||||
if (eAc3) {
|
if (eAc3) {
|
||||||
hlsVideoAudioCodecs.push('eac3');
|
hlsVideoAudioCodecs.push('eac3');
|
||||||
|
@ -475,14 +484,24 @@ define(['browser'], function (browser) {
|
||||||
mp4VideoCodecs.push('h264');
|
mp4VideoCodecs.push('h264');
|
||||||
hlsVideoCodecs.push('h264');
|
hlsVideoCodecs.push('h264');
|
||||||
}
|
}
|
||||||
if (canPlayH265(videoTestElement, options)) {
|
|
||||||
|
if (canPlayH265(videoTestElement)) {
|
||||||
mp4VideoCodecs.push('h265');
|
mp4VideoCodecs.push('h265');
|
||||||
mp4VideoCodecs.push('hevc');
|
mp4VideoCodecs.push('hevc');
|
||||||
|
}
|
||||||
|
|
||||||
if (browser.tizen || browser.web0s) {
|
if (canPlayH265(videoTestElement, 'hls')) {
|
||||||
hlsVideoCodecs.push('h265');
|
hlsVideoCodecs.push('h265');
|
||||||
hlsVideoCodecs.push('hevc');
|
hlsVideoCodecs.push('hevc');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (canPlayH265(videoTestElement) && (browser.tizen || browser.web0s)) {
|
||||||
|
if (hlsVideoCodecs.indexOf('h265') === -1) {
|
||||||
|
hlsVideoCodecs.push('h265');
|
||||||
|
}
|
||||||
|
if (hlsVideoCodecs.indexOf('hevc') === -1) {
|
||||||
|
hlsVideoCodecs.push('hevc');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (supportsMpeg2Video()) {
|
if (supportsMpeg2Video()) {
|
||||||
|
@ -557,10 +576,10 @@ define(['browser'], function (browser) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// aac also appears in the m4a container
|
// aac also appears in the m4a and m4b container
|
||||||
if (audioFormat === 'aac' || audioFormat === 'alac') {
|
if (audioFormat === 'aac' || audioFormat === 'alac') {
|
||||||
profile.DirectPlayProfiles.push({
|
profile.DirectPlayProfiles.push({
|
||||||
Container: 'm4a',
|
Container: 'm4a,m4b',
|
||||||
AudioCodec: audioFormat,
|
AudioCodec: audioFormat,
|
||||||
Type: 'Audio'
|
Type: 'Audio'
|
||||||
});
|
});
|
||||||
|
@ -652,7 +671,7 @@ define(['browser'], function (browser) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (canPlayHls() && options.enableHls !== false) {
|
if (canPlayHls() && hlsVideoAudioCodecs.length && options.enableHls !== false) {
|
||||||
profile.TranscodingProfiles.push({
|
profile.TranscodingProfiles.push({
|
||||||
Container: 'ts',
|
Container: 'ts',
|
||||||
Type: 'Video',
|
Type: 'Video',
|
||||||
|
@ -750,9 +769,27 @@ define(['browser'], function (browser) {
|
||||||
var maxH264Level = browser.chromecast ? 42 : 51;
|
var maxH264Level = browser.chromecast ? 42 : 51;
|
||||||
var h264Profiles = 'high|main|baseline|constrained baseline';
|
var h264Profiles = 'high|main|baseline|constrained baseline';
|
||||||
|
|
||||||
if (maxH264Level >= 51 && browser.chrome && !browser.osx) {
|
if (browser.tizen || browser.orsay || browser.web0s ||
|
||||||
|
videoTestElement.canPlayType('video/mp4; codecs="avc1.640833"').replace(/no/, '')) {
|
||||||
|
maxH264Level = 51;
|
||||||
|
}
|
||||||
|
|
||||||
|
var userAgent = navigator.userAgent.toLowerCase();
|
||||||
|
if (browser.chromecast) {
|
||||||
|
var isChromecastUltra = userAgent.indexOf('aarch64') !== -1;
|
||||||
|
if (isChromecastUltra) {
|
||||||
|
maxH264Level = 51;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (browser.tizen || browser.orsay ||
|
||||||
|
videoTestElement.canPlayType('video/mp4; codecs="avc1.6e0033"').replace(/no/, '')) {
|
||||||
|
|
||||||
|
// These tests are passing in safari, but playback is failing
|
||||||
|
if (!browser.safari && !browser.iOS && !browser.web0s) {
|
||||||
h264Profiles += '|high 10';
|
h264Profiles += '|high 10';
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
profile.CodecProfiles.push({
|
profile.CodecProfiles.push({
|
||||||
Type: 'Video',
|
Type: 'Video',
|
||||||
|
@ -767,12 +804,14 @@ define(['browser'], function (browser) {
|
||||||
{
|
{
|
||||||
Condition: 'EqualsAny',
|
Condition: 'EqualsAny',
|
||||||
Property: 'VideoProfile',
|
Property: 'VideoProfile',
|
||||||
Value: h264Profiles
|
Value: h264Profiles,
|
||||||
|
IsRequired: false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Condition: 'LessThanEqual',
|
Condition: 'LessThanEqual',
|
||||||
Property: 'VideoLevel',
|
Property: 'VideoLevel',
|
||||||
Value: maxH264Level.toString()
|
Value: maxH264Level.toString(),
|
||||||
|
IsRequired: false
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue