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