diff --git a/src/components/htmlMediaHelper.js b/src/components/htmlMediaHelper.js index 4077d29447..ab1a215656 100644 --- a/src/components/htmlMediaHelper.js +++ b/src/components/htmlMediaHelper.js @@ -28,6 +28,16 @@ function canPlayNativeHls() { || media.canPlayType('application/vnd.apple.mpegURL').replace(/no/, '')); } +export function enableHlsJsPlayerForCodecs(mediaSource, mediaType) { + // Workaround for VP9 HLS support on desktop Safari + // Force using HLS.js because desktop Safari's native HLS player does not play VP9 over HLS + // browser.osx will return true on iPad, cannot use + if (!browser.iOS && browser.safari && mediaSource.MediaStreams.some(x => x.Codec === 'vp9')) { + return true; + } + return enableHlsJsPlayer(mediaSource.RunTimeTicks, mediaType); +} + export function enableHlsJsPlayer(runTimeTicks, mediaType) { if (window.MediaSource == null) { return false; diff --git a/src/plugins/htmlVideoPlayer/plugin.js b/src/plugins/htmlVideoPlayer/plugin.js index 3b15d20a51..83e247eb83 100644 --- a/src/plugins/htmlVideoPlayer/plugin.js +++ b/src/plugins/htmlVideoPlayer/plugin.js @@ -12,7 +12,7 @@ import { destroyFlvPlayer, destroyCastPlayer, getCrossOriginValue, - enableHlsJsPlayer, + enableHlsJsPlayerForCodecs, applySrc, resetSrc, playWithPromise, @@ -515,7 +515,7 @@ export class HtmlVideoPlayer { elem.crossOrigin = crossOrigin; } - if (enableHlsJsPlayer(options.mediaSource.RunTimeTicks, 'Video') && isHls(options.mediaSource)) { + if (enableHlsJsPlayerForCodecs(options.mediaSource, 'Video') && isHls(options.mediaSource)) { return this.setSrcWithHlsJs(elem, options, val); } else if (options.playMethod !== 'Transcode' && options.mediaSource.Container?.toUpperCase() === 'FLV') { return this.setSrcWithFlvJs(elem, options, val); diff --git a/src/scripts/browserDeviceProfile.js b/src/scripts/browserDeviceProfile.js index 85089e6d0e..f3c6b9a2aa 100644 --- a/src/scripts/browserDeviceProfile.js +++ b/src/scripts/browserDeviceProfile.js @@ -453,6 +453,7 @@ export default function (options) { const canPlayVp8 = videoTestElement.canPlayType('video/webm; codecs="vp8"').replace(/no/, ''); const canPlayVp9 = videoTestElement.canPlayType('video/webm; codecs="vp9"').replace(/no/, ''); + const safariSupportsOpus = browser.safari && !!document.createElement('audio').canPlayType('audio/x-caf; codecs="opus"').replace(/no/, ''); const webmAudioCodecs = ['vorbis']; const canPlayMkv = testCanPlayMkv(videoTestElement); @@ -582,9 +583,11 @@ export default function (options) { if (browser.tizen) { hlsInTsVideoAudioCodecs.push('opus'); } - if (!browser.safari) { - hlsInFmp4VideoAudioCodecs.push('opus'); - } + hlsInFmp4VideoAudioCodecs.push('opus'); + } else if (safariSupportsOpus) { + videoAudioCodecs.push('opus'); + webmAudioCodecs.push('opus'); + hlsInFmp4VideoAudioCodecs.push('opus'); } // FLAC audio in video plays with a delay on Tizen @@ -657,7 +660,16 @@ export default function (options) { } if (canPlayVp9) { - mp4VideoCodecs.push('vp9'); + if (!browser.iOS) { + // iOS safari may fail to direct play vp9 in mp4 container + mp4VideoCodecs.push('vp9'); + } + // Only iOS Safari's native HLS player understands vp9 in fmp4 + // This should be used in conjunction with forcing + // using HLS.js for VP9 remuxing on desktop Safari. + if (browser.safari) { + hlsInFmp4VideoCodecs.push('vp9'); + } // webm support is unreliable on safari 17 if (!browser.safari || (browser.safari && browser.versionMajor >= 15 && browser.versionMajor < 17)) { @@ -674,7 +686,7 @@ export default function (options) { } } - if (canPlayVp8 || browser.tizen) { + if ((!browser.safari && canPlayVp8) || browser.tizen) { videoAudioCodecs.push('vorbis'); } @@ -757,6 +769,14 @@ export default function (options) { } }); + if (safariSupportsOpus) { + profile.DirectPlayProfiles.push({ + Container: 'mp4', + AudioCodec: 'opus', + Type: 'Audio' + }); + } + profile.TranscodingProfiles = []; const hlsBreakOnNonKeyFrames = browser.iOS || browser.osx || browser.edge || !canPlayNativeHls();