diff --git a/ghost/oembed-service/lib/OEmbedService.js b/ghost/oembed-service/lib/OEmbedService.js
index c9876027bb..dc7b7cce48 100644
--- a/ghost/oembed-service/lib/OEmbedService.js
+++ b/ghost/oembed-service/lib/OEmbedService.js
@@ -373,6 +373,18 @@ class OEmbedService {
try {
const urlObject = new URL(url);
+ // YouTube has started not returning oembed tags for some live URLs
+ // when fetched from an IP address that's in a non-EN region.
+ // We convert live URLs to watch URLs so we can go straight to the
+ // oembed request via a known provider rather than going through the page fetch routine.
+ const ytLiveRegex = /^\/live\/([a-zA-Z0-9_-]+)$/;
+ if (urlObject.hostname === 'www.youtube.com' && ytLiveRegex.test(urlObject.pathname)) {
+ const videoId = ytLiveRegex.exec(urlObject.pathname)[1];
+ urlObject.pathname = '/watch';
+ urlObject.searchParams.set('v', videoId);
+ url = urlObject.toString();
+ }
+
// Trimming solves the difference of url validation between `new URL(url)`
// and metascraper.
url = url.trim();
diff --git a/ghost/oembed-service/test/oembed-service.test.js b/ghost/oembed-service/test/oembed-service.test.js
index 18adf678e2..2e4d45984f 100644
--- a/ghost/oembed-service/test/oembed-service.test.js
+++ b/ghost/oembed-service/test/oembed-service.test.js
@@ -172,5 +172,31 @@ describe('oembed-service', function () {
assert.equal(response.url, 'https://www.example.com');
assert.equal(response.metadata.title, 'Example');
});
+
+ it('converts YT live URLs to watch URLs', async function () {
+ nock('https://www.youtube.com')
+ .get('/oembed')
+ .query((query) => {
+ // Ensure the URL is converted to a watch URL and retains existing query params.
+ const actual = query.url;
+ const expected = 'https://youtube.com/watch?param=existing&v=1234';
+
+ assert.equal(actual, expected, 'URL passed to oembed endpoint is incorrect');
+
+ return actual === expected;
+ })
+ .reply(200, {
+ type: 'rich',
+ version: '1.0',
+ title: 'Test Title',
+ author_name: 'Test Author',
+ author_url: 'https://example.com/user/testauthor',
+ html: '',
+ width: 640,
+ height: null
+ });
+
+ await oembedService.fetchOembedDataFromUrl('https://www.youtube.com/live/1234?param=existing');
+ });
});
});