From a386512defd8d8875f2a9b8501874e71e7a844f5 Mon Sep 17 00:00:00 2001 From: gnattu Date: Sun, 4 Aug 2024 13:55:05 +0800 Subject: [PATCH 1/3] Better codec profile for Safari with 10.10 features This uses the new VP9 remuxing and audio remuxing features to reduce transcoding on Safari, also removed some problematic direct play profiles. - Add opus profile for Safari - Add VP9 remuxing profile for Safari - Remove Vorbis profile on non-webm container for Safari - Remove direct VP9 playback in mp4 container for iOS Safari --- src/components/htmlMediaHelper.js | 10 +++++++++ src/plugins/htmlVideoPlayer/plugin.js | 3 ++- src/scripts/browserDeviceProfile.js | 30 ++++++++++++++++++++++++--- 3 files changed, 39 insertions(+), 4 deletions(-) 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(); From 0e985c2ffe370ff62918313b02ef265b3f0f4012 Mon Sep 17 00:00:00 2001 From: gnattu Date: Sun, 4 Aug 2024 14:18:42 +0800 Subject: [PATCH 2/3] fix lint --- src/components/htmlMediaHelper.js | 4 ++-- src/plugins/htmlVideoPlayer/plugin.js | 1 - src/scripts/browserDeviceProfile.js | 10 ++++------ 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/src/components/htmlMediaHelper.js b/src/components/htmlMediaHelper.js index 21cb84e41e..c7fe3145f7 100644 --- a/src/components/htmlMediaHelper.js +++ b/src/components/htmlMediaHelper.js @@ -33,9 +33,9 @@ export function enableHlsJsPlayerForCodecs(mediaSource, mediaType) { // 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 true; } - return enableHlsJsPlayer(mediaSource.RunTimeTicks, mediaType) + return enableHlsJsPlayer(mediaSource.RunTimeTicks, mediaType); } export function enableHlsJsPlayer(runTimeTicks, mediaType) { diff --git a/src/plugins/htmlVideoPlayer/plugin.js b/src/plugins/htmlVideoPlayer/plugin.js index a0738ee11d..224f43a76a 100644 --- a/src/plugins/htmlVideoPlayer/plugin.js +++ b/src/plugins/htmlVideoPlayer/plugin.js @@ -12,7 +12,6 @@ import { destroyFlvPlayer, destroyCastPlayer, getCrossOriginValue, - enableHlsJsPlayer, enableHlsJsPlayerForCodecs, applySrc, resetSrc, diff --git a/src/scripts/browserDeviceProfile.js b/src/scripts/browserDeviceProfile.js index 3d9d08a777..1270004854 100644 --- a/src/scripts/browserDeviceProfile.js +++ b/src/scripts/browserDeviceProfile.js @@ -584,12 +584,10 @@ export default function (options) { hlsInFmp4VideoAudioCodecs.push('opus'); } - if (browser.safari) { - if (safariSupportsOpus) { - videoAudioCodecs.push('opus'); - webmAudioCodecs.push('opus'); - hlsInFmp4VideoAudioCodecs.push('opus'); - } + if (safariSupportsOpus) { + videoAudioCodecs.push('opus'); + webmAudioCodecs.push('opus'); + hlsInFmp4VideoAudioCodecs.push('opus'); } // FLAC audio in video plays with a delay on Tizen From 6195e119221e46ef7e21de1afc2768a75eb83017 Mon Sep 17 00:00:00 2001 From: gnattu Date: Wed, 21 Aug 2024 04:50:18 +0800 Subject: [PATCH 3/3] Use else if just in case safari changed behavior in future --- src/scripts/browserDeviceProfile.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/scripts/browserDeviceProfile.js b/src/scripts/browserDeviceProfile.js index 1270004854..e1626c8dfc 100644 --- a/src/scripts/browserDeviceProfile.js +++ b/src/scripts/browserDeviceProfile.js @@ -582,9 +582,7 @@ export default function (options) { hlsInTsVideoAudioCodecs.push('opus'); } hlsInFmp4VideoAudioCodecs.push('opus'); - } - - if (safariSupportsOpus) { + } else if (safariSupportsOpus) { videoAudioCodecs.push('opus'); webmAudioCodecs.push('opus'); hlsInFmp4VideoAudioCodecs.push('opus');