diff --git a/src/renderer/components/ft-video-player/ft-video-player.js b/src/renderer/components/ft-video-player/ft-video-player.js index 5c9c6992f..835a56077 100644 --- a/src/renderer/components/ft-video-player/ft-video-player.js +++ b/src/renderer/components/ft-video-player/ft-video-player.js @@ -17,11 +17,17 @@ import { sponsorBlockSkipSegments } from '../../helpers/sponsorblock' import { calculateColorLuminance, colors } from '../../helpers/colors' import { pathExists } from '../../helpers/filesystem' import { getPicturesPath, showSaveDialog, showToast } from '../../helpers/utils' +import { getProxyUrl } from '../../helpers/api/invidious' +import store from '../../store' // YouTube now throttles if you use the `Range` header for the DASH formats, instead of the range query parameter // videojs-http-streaming calls this hook everytime it makes a request, // so we can use it to convert the Range header into the range query parameter for the streaming URLs videojs.Vhs.xhr.beforeRequest = (options) => { + if (store.getters.getProxyVideos) { + const { uri } = options + options.uri = getProxyUrl(uri) + } // pass in the optional base so it doesn't error for `dashFiles/videoId.xml` (DASH manifest in dev mode) if (new URL(options.uri, window.location.origin).hostname.endsWith('.googlevideo.com')) { // The official clients use POST requests with this body for the DASH requests, so we should do that too @@ -34,7 +40,6 @@ videojs.Vhs.xhr.beforeRequest = (options) => { } } } - // videojs-http-streaming spits out a warning every time you access videojs.Vhs.BANDWIDTH_VARIANCE // so we'll get the value once here, to stop it spamming the console // https://github.com/videojs/http-streaming/blob/main/src/config.js#L8-L10 @@ -304,6 +309,10 @@ export default defineComponent({ screenshotFolder: function() { return this.$store.getters.getScreenshotFolderPath + }, + + proxyVideos: function () { + return this.$store.getters.getProxyVideos } }, watch: { @@ -1224,7 +1233,15 @@ export default defineComponent({ this.useDash = false this.useHls = false - this.activeSourceList = this.sourceList + this.activeSourceList = (this.proxyVideos || !process.env.IS_ELECTRON) + // use map here to return slightly different list without modifying original + ? this.sourceList.map((source) => { + return { + ...source, + url: getProxyUrl(source.url) + } + }) + : this.sourceList setTimeout(this.initializePlayer, 100) }, diff --git a/src/renderer/helpers/api/invidious.js b/src/renderer/helpers/api/invidious.js index c9ff317ef..c2ca54dc6 100644 --- a/src/renderer/helpers/api/invidious.js +++ b/src/renderer/helpers/api/invidious.js @@ -6,6 +6,16 @@ function getCurrentInstance() { return store.getters.getCurrentInvidiousInstance } +export function getProxyUrl(uri) { + const url = new URL(uri) + const { origin } = url + if (!url.searchParams.has('host') && origin !== getCurrentInstance()) { + // invidious requires host param to be filled with the origin of the stream + url.searchParams.append('host', origin.replace('https://', '')) + } + return url.toString().replace(origin, getCurrentInstance()) +} + export function invidiousAPICall({ resource, id = '', params = {}, doLogError = true, subResource = '' }) { return new Promise((resolve, reject) => { const requestUrl = getCurrentInstance() + '/api/v1/' + resource + '/' + id + (!isNullOrEmpty(subResource) ? `/${subResource}` : '') + '?' + new URLSearchParams(params).toString()