diff --git a/src/components/htmlMediaHelper.js b/src/components/htmlMediaHelper.js
index fa1b343caa..21cb84e41e 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 5c536e7e11..a0738ee11d 100644
--- a/src/plugins/htmlVideoPlayer/plugin.js
+++ b/src/plugins/htmlVideoPlayer/plugin.js
@@ -13,6 +13,7 @@ import {
destroyCastPlayer,
getCrossOriginValue,
enableHlsJsPlayer,
+ enableHlsJsPlayerForCodecs,
applySrc,
resetSrc,
playWithPromise,
@@ -515,7 +516,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 4bda92547d..3d9d08a777 100644
--- a/src/scripts/browserDeviceProfile.js
+++ b/src/scripts/browserDeviceProfile.js
@@ -451,6 +451,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);
@@ -580,7 +581,13 @@ export default function (options) {
if (browser.tizen) {
hlsInTsVideoAudioCodecs.push('opus');
}
- if (!browser.safari) {
+ hlsInFmp4VideoAudioCodecs.push('opus');
+ }
+
+ if (browser.safari) {
+ if (safariSupportsOpus) {
+ videoAudioCodecs.push('opus');
+ webmAudioCodecs.push('opus');
hlsInFmp4VideoAudioCodecs.push('opus');
}
}
@@ -655,7 +662,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)) {
@@ -672,7 +688,7 @@ export default function (options) {
}
}
- if (canPlayVp8 || browser.tizen) {
+ if ((!browser.safari && canPlayVp8) || browser.tizen) {
videoAudioCodecs.push('vorbis');
}
@@ -744,6 +760,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();