diff --git a/dashboard-ui/bower_components/emby-webcomponents/browserdeviceprofile.js b/dashboard-ui/bower_components/emby-webcomponents/browserdeviceprofile.js index a2c62e9bb7..7ebb3cca97 100644 --- a/dashboard-ui/bower_components/emby-webcomponents/browserdeviceprofile.js +++ b/dashboard-ui/bower_components/emby-webcomponents/browserdeviceprofile.js @@ -159,7 +159,7 @@ define(['browser'], function (browser) { break; case 'mpg': case 'mpeg': - supported = browser.edgeUwp; + supported = browser.edgeUwp || browser.tizen; break; case '3gp': case 'flv': @@ -170,7 +170,7 @@ define(['browser'], function (browser) { supported = browser.tizen; break; case 'mov': - supported = browser.chrome || browser.edgeUwp; + supported = browser.tizen || browser.chrome || browser.edgeUwp; videoCodecs.push('h264'); break; case 'm2ts': @@ -184,6 +184,10 @@ define(['browser'], function (browser) { case 'ts': supported = testCanPlayTs(); videoCodecs.push('h264'); + if (canPlayH265()) { + videoCodecs.push('h265'); + videoCodecs.push('hevc'); + } profileContainer = 'ts,mpegts'; break; default: @@ -205,7 +209,7 @@ define(['browser'], function (browser) { function getMaxBitrate() { if (browser.edgeUwp) { - return 32000000; + return 40000000; } // 10mbps @@ -236,7 +240,7 @@ define(['browser'], function (browser) { return function (options) { options = options || {}; - var physicalAudioChannels = options.audioChannels || 2; + var physicalAudioChannels = options.audioChannels || (browser.tv || browser.xboxOne || browser.ps4 ? 6 : 2); var bitrateSetting = getMaxBitrate(); @@ -263,16 +267,21 @@ define(['browser'], function (browser) { // Only put mp3 first if mkv support is there // Otherwise with HLS and mp3 audio we're seeing some browsers // safari is lying - if ((videoTestElement.canPlayType('audio/mp4; codecs="ac-3"').replace(/no/, '') && !browser.safari) || browser.edgeUwp || browser.tizen) { + if ((videoTestElement.canPlayType('audio/mp4; codecs="ac-3"').replace(/no/, '') && !browser.osx && !browser.iOS) || browser.edgeUwp || browser.tizen || browser.web0s) { videoAudioCodecs.push('ac3'); // This works in edge desktop, but not mobile // TODO: Retest this on mobile - if (!browser.edge || !browser.touch) { + if (!browser.edge || !browser.touch || browser.edgeUwp) { hlsVideoAudioCodecs.push('ac3'); } } + if (browser.tizen) { + videoAudioCodecs.push('eac3'); + hlsVideoAudioCodecs.push('eac3'); + } + var mp3Added = false; if (canPlayMkv) { if (supportsMp3VideoAudio) { @@ -288,10 +297,13 @@ define(['browser'], function (browser) { if (!mp3Added) { videoAudioCodecs.push('mp3'); } - hlsVideoAudioCodecs.push('mp3'); + if (!browser.ps4) { + // PS4 fails to load HLS with mp3 audio + hlsVideoAudioCodecs.push('mp3'); + } } - if (browser.tizen) { + if (browser.tizen || options.supportsDts) { videoAudioCodecs.push('dca'); videoAudioCodecs.push('dts'); } @@ -300,7 +312,7 @@ define(['browser'], function (browser) { //videoAudioCodecs.push('truehd'); } - videoAudioCodecs = videoAudioCodecs.filter(function(c) { + videoAudioCodecs = videoAudioCodecs.filter(function (c) { return (options.disableVideoAudioCodecs || []).indexOf(c) === -1; }); @@ -326,6 +338,11 @@ define(['browser'], function (browser) { }); } + if (browser.tizen) { + mp4VideoCodecs.push('mpeg2video'); + mp4VideoCodecs.push('vc1'); + } + if (canPlayMkv && mp4VideoCodecs.length) { profile.DirectPlayProfiles.push({ Container: 'mkv', @@ -379,21 +396,23 @@ define(['browser'], function (browser) { profile.TranscodingProfiles = []; - ['opus', 'mp3', 'aac'].filter(canPlayAudioFormat).forEach(function (audioFormat) { + ['opus', 'mp3', 'aac', 'wav'].filter(canPlayAudioFormat).forEach(function (audioFormat) { profile.TranscodingProfiles.push({ Container: audioFormat, Type: 'Audio', AudioCodec: audioFormat, Context: 'Streaming', - Protocol: 'http' + Protocol: 'http', + MaxAudioChannels: physicalAudioChannels.toString() }); profile.TranscodingProfiles.push({ Container: audioFormat, Type: 'Audio', AudioCodec: audioFormat, Context: 'Static', - Protocol: 'http' + Protocol: 'http', + MaxAudioChannels: physicalAudioChannels.toString() }); }); @@ -424,7 +443,7 @@ define(['browser'], function (browser) { Context: 'Streaming', Protocol: 'hls', MaxAudioChannels: physicalAudioChannels.toString(), - EnableSplittingOnNonKeyFrames: browser.safari ? true : false + EnableSplittingOnNonKeyFrames: (browser.osx || browser.iOS) ? true : false }); } @@ -481,14 +500,8 @@ define(['browser'], function (browser) { profile.ContainerProfiles = []; profile.CodecProfiles = []; - profile.CodecProfiles.push({ - Type: 'Audio', - Conditions: [{ - Condition: 'LessThanEqual', - Property: 'AudioChannels', - Value: '2' - }] - }); + + var supportsSecondaryAudio = browser.tizen; // Handle he-aac not supported if (!videoTestElement.canPlayType('video/mp4; codecs="avc1.640029, mp4a.40.5"').replace(/no/, '')) { @@ -505,7 +518,24 @@ define(['browser'], function (browser) { Condition: 'LessThanEqual', Property: 'AudioBitrate', Value: '128000' - }, + } + ] + }); + + if (!supportsSecondaryAudio) { + profile.CodecProfiles[profile.CodecProfiles.length - 1].Conditions.push({ + Condition: 'Equals', + Property: 'IsSecondaryAudio', + Value: 'false', + IsRequired: 'false' + }); + } + } + + if (!supportsSecondaryAudio) { + profile.CodecProfiles.push({ + Type: 'VideoAudio', + Conditions: [ { Condition: 'Equals', Property: 'IsSecondaryAudio', @@ -516,18 +546,6 @@ define(['browser'], function (browser) { }); } - profile.CodecProfiles.push({ - Type: 'VideoAudio', - Conditions: [ - { - Condition: 'Equals', - Property: 'IsSecondaryAudio', - Value: 'false', - IsRequired: 'false' - } - ] - }); - var maxLevel = '41'; if (browser.chrome && !browser.mobile) { @@ -565,18 +583,6 @@ define(['browser'], function (browser) { }); } - profile.CodecProfiles.push({ - Type: 'Video', - Codec: 'vpx', - Conditions: [ - { - Condition: 'NotEquals', - Property: 'IsAnamorphic', - Value: 'true', - IsRequired: false - }] - }); - // Subtitle profiles // External vtt or burn in profile.SubtitleProfiles = []; diff --git a/dashboard-ui/scripts/mediaplayer.js b/dashboard-ui/scripts/mediaplayer.js index badca83b10..456147336e 100644 --- a/dashboard-ui/scripts/mediaplayer.js +++ b/dashboard-ui/scripts/mediaplayer.js @@ -1,4 +1,5 @@ -define(['appSettings', 'userSettings', 'appStorage', 'datetime'], function (appSettings, userSettings, appStorage, datetime) { +define(['appSettings', 'userSettings', 'datetime', 'browser'], function (appSettings, userSettings, datetime, browser) { + 'use strict'; function mediaPlayer() { @@ -96,7 +97,7 @@ define(['appSettings', 'userSettings', 'appStorage', 'datetime'], function (appS var intervalTime = ApiClient.isWebSocketOpen() ? 1200 : 5000; // Ease up with safari because it doesn't perform as well - if (browserInfo.safari) { + if (browser.safari) { intervalTime = Math.max(intervalTime, 5000); } self.lastProgressReport = 0; @@ -153,7 +154,7 @@ define(['appSettings', 'userSettings', 'appStorage', 'datetime'], function (appS if (!AppInfo.isNativeApp) { var disableHlsVideoAudioCodecs = []; - if (!self.canPlayNativeHls() || (browserInfo.edge && !item.RunTimeTicks)) { + if (!self.canPlayNativeHls() || (browser.edge && !item.RunTimeTicks)) { // hls.js does not support these disableHlsVideoAudioCodecs.push('mp3'); disableHlsVideoAudioCodecs.push('ac3'); @@ -431,26 +432,26 @@ define(['appSettings', 'userSettings', 'appStorage', 'datetime'], function (appS Dashboard.showLoadingMsg(); - Dashboard.getCurrentUser().then(function (user) { + return Dashboard.getCurrentUser().then(function (user) { if (options.items) { - translateItemsForPlayback(options.items, true).then(function (items) { + return translateItemsForPlayback(options.items, true).then(function (items) { - self.playWithIntros(items, options, user); + return self.playWithIntros(items, options, user); }); } else { - self.getItemsForPlayback({ + return self.getItemsForPlayback({ Ids: options.ids.join(',') }).then(function (result) { - translateItemsForPlayback(result.Items, true).then(function (items) { + return translateItemsForPlayback(result.Items, true).then(function (items) { - self.playWithIntros(items, options, user); + return self.playWithIntros(items, options, user); }); }); @@ -486,12 +487,14 @@ define(['appSettings', 'userSettings', 'appStorage', 'datetime'], function (appS }); }); + // Todo: rework above methods to use promises + return Promise.resolve(); }; - function getOptimalMediaSource(mediaType, versions) { + function getOptimalMediaSource(mediaType, itemType, versions) { var promises = versions.map(function (v) { - return MediaController.supportsDirectPlay(v); + return MediaController.supportsDirectPlay(v, itemType); }); return Promise.all(promises).then(function (responses) { @@ -667,8 +670,6 @@ define(['appSettings', 'userSettings', 'appStorage', 'datetime'], function (appS }); }; - self.lastBitrateDetections = {}; - self.playInternal = function (item, startPosition, callback) { if (item == null) { @@ -696,15 +697,12 @@ define(['appSettings', 'userSettings', 'appStorage', 'datetime'], function (appS }); }; - var bitrateDetectionKey = ApiClient.serverAddress(); - - if (item.MediaType == 'Video' && appSettings.enableAutomaticBitrateDetection() && (new Date().getTime() - (self.lastBitrateDetections[bitrateDetectionKey] || 0)) > 300000) { + if (item.MediaType == 'Video' && appSettings.enableAutomaticBitrateDetection()) { Dashboard.showLoadingMsg(); ApiClient.detectBitrate().then(function (bitrate) { console.log('Max bitrate auto detected to ' + bitrate); - self.lastBitrateDetections[bitrateDetectionKey] = new Date().getTime(); appSettings.maxStreamingBitrate(bitrate); onBitrateDetected(); @@ -727,14 +725,14 @@ define(['appSettings', 'userSettings', 'appStorage', 'datetime'], function (appS if (validatePlaybackInfoResult(playbackInfoResult)) { - getOptimalMediaSource(item.MediaType, playbackInfoResult.MediaSources).then(function (mediaSource) { + getOptimalMediaSource(item.MediaType, item.Type, playbackInfoResult.MediaSources).then(function (mediaSource) { if (mediaSource) { if (mediaSource.RequiresOpening) { MediaController.getLiveStream(item.Id, playbackInfoResult.PlaySessionId, deviceProfile, startPosition, mediaSource, null, null).then(function (openLiveStreamResult) { - MediaController.supportsDirectPlay(openLiveStreamResult.MediaSource).then(function (result) { + MediaController.supportsDirectPlay(openLiveStreamResult.MediaSource, item.Type).then(function (result) { openLiveStreamResult.MediaSource.enableDirectPlay = result; callback(openLiveStreamResult.MediaSource); @@ -1092,13 +1090,13 @@ define(['appSettings', 'userSettings', 'appStorage', 'datetime'], function (appS self.saveVolume = function (val) { if (val) { - appStorage.setItem("volume", val); + appSettings.set("volume", val); } }; self.getSavedVolume = function () { - return appStorage.getItem("volume") || 0.5; + return appSettings.get("volume") || 0.5; }; self.shuffle = function (id) { @@ -1487,7 +1485,7 @@ define(['appSettings', 'userSettings', 'appStorage', 'datetime'], function (appS return true; } - if (browserInfo.mobile) { + if (browser.mobile) { return false; }