From d2e22ff8ae1eed79762872f5db0e6038a9dd7d3d Mon Sep 17 00:00:00 2001 From: Alex Barstow Date: Tue, 8 Oct 2024 14:09:43 -0400 Subject: [PATCH 1/3] use source elements when overriding native hls in safari in order to support airplay, add test --- src/videojs-http-streaming.js | 9 ++++++- test/videojs-http-streaming.test.js | 39 +++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/src/videojs-http-streaming.js b/src/videojs-http-streaming.js index 1a6b75306..a88c6d7b2 100644 --- a/src/videojs-http-streaming.js +++ b/src/videojs-http-streaming.js @@ -1079,7 +1079,14 @@ class VhsHandler extends Component { this.mediaSourceUrl_ = window.URL.createObjectURL(this.playlistController_.mediaSource); - this.tech_.src(this.mediaSourceUrl_); + // If we are playing HLS with MSE in Safari, add source elements for both the blob and manifest URLs. + // The latter will enable Airplay playback on receiver devices. + if ((videojs.browser.IS_ANY_SAFARI || videojs.browser.IS_IOS) && this.options_.overrideNative && this.options_.sourceType === 'hls') { + this.tech_.addSourceElement(this.mediaSourceUrl_); + this.tech_.addSourceElement(this.source_.src); + } else { + this.tech_.src(this.mediaSourceUrl_); + } } createKeySessions_() { diff --git a/test/videojs-http-streaming.test.js b/test/videojs-http-streaming.test.js index 929dc00b6..027ca75b1 100644 --- a/test/videojs-http-streaming.test.js +++ b/test/videojs-http-streaming.test.js @@ -3121,6 +3121,45 @@ QUnit.test( } ); +QUnit.test('uses source elements when overriding native HLS in Safari/iOS', function(assert) { + const origIsAnySafari = videojs.browser.IS_ANY_SAFARI; + const addSourceElementCalls = []; + let srcCalls = 0; + + videojs.browser.IS_ANY_SAFARI = true; + + const player = createPlayer({ html5: { vhs: { overrideNative: true } } }); + + player.tech_.addSourceElement = function(url) { + addSourceElementCalls.push(url); + }; + + player.tech_.src = function() { + srcCalls++; + }; + + player.src({ + src: 'http://example.com/manifest/main.m3u8', + type: 'application/x-mpegURL' + }); + + this.clock.tick(1); + + assert.equal(addSourceElementCalls.length, 2, '2 source elements added'); + assert.equal(srcCalls, 0, 'tech.src() not called'); + + const blobUrl = addSourceElementCalls[0]; + const manifestUrl = addSourceElementCalls[1]; + + assert.ok(blobUrl.startsWith('blob:'), 'First source element is a blob URL'); + assert.equal(manifestUrl, 'http://example.com/manifest/main.m3u8', 'Second source element is the manifest URL'); + + // Clean up and restore original flags + player.dispose(); + + videojs.browser.IS_ANY_SAFARI = origIsAnySafari; +}); + QUnit.test('re-emits mediachange events', function(assert) { let mediaChanges = 0; From 29b43026a4e488a7b19f0707eb95c0c887879ec7 Mon Sep 17 00:00:00 2001 From: Alex Barstow Date: Wed, 9 Oct 2024 10:34:16 -0400 Subject: [PATCH 2/3] make sure addSourceElement method exists --- src/videojs-http-streaming.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/videojs-http-streaming.js b/src/videojs-http-streaming.js index a88c6d7b2..404b5927a 100644 --- a/src/videojs-http-streaming.js +++ b/src/videojs-http-streaming.js @@ -1081,7 +1081,12 @@ class VhsHandler extends Component { // If we are playing HLS with MSE in Safari, add source elements for both the blob and manifest URLs. // The latter will enable Airplay playback on receiver devices. - if ((videojs.browser.IS_ANY_SAFARI || videojs.browser.IS_IOS) && this.options_.overrideNative && this.options_.sourceType === 'hls') { + if (( + videojs.browser.IS_ANY_SAFARI || videojs.browser.IS_IOS) && + this.options_.overrideNative && + this.options_.sourceType === 'hls' && + typeof this.tech_.addSourceElement === 'function' + ) { this.tech_.addSourceElement(this.mediaSourceUrl_); this.tech_.addSourceElement(this.source_.src); } else { From 482c2c412ab5b295c44fb7ec0260421487d08310 Mon Sep 17 00:00:00 2001 From: Alex Barstow Date: Wed, 9 Oct 2024 12:52:42 -0400 Subject: [PATCH 3/3] bump peer dep version of video.js --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f3670db03..b5e514bb1 100644 --- a/package.json +++ b/package.json @@ -67,7 +67,7 @@ "video.js": "^7 || ^8" }, "peerDependencies": { - "video.js": "^8.14.0" + "video.js": "^8.19.0" }, "devDependencies": { "@babel/cli": "^7.21.0",