Skip to content

Commit

Permalink
Merge branch 'development' into custom-builds/current
Browse files Browse the repository at this point in the history
* development:
  Fix video throttling because of range header (FreeTubeApp#3234)
  Translated using Weblate (Greek)
  Migrate channel related functionality to YouTube.js (FreeTubeApp#3143)
  Differentiate links in readme.md (FreeTubeApp#3224)
  • Loading branch information
PikachuEXE committed Mar 1, 2023
2 parents 224fe4e + f56f6e7 commit cd2b314
Show file tree
Hide file tree
Showing 22 changed files with 973 additions and 387 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ If you have issues with the extension working with FreeTube, please create an is

* [FreeTube Website](https://freetubeapp.io/#download)

* Flatpak on Flathub: [Download](https://flathub.org/apps/details/io.freetubeapp.FreeTube) [Source](https://github.com/flathub/io.freetubeapp.FreeTube)
* Flatpak on Flathub: [Download](https://flathub.org/apps/details/io.freetubeapp.FreeTube) and [Source](https://github.com/flathub/io.freetubeapp.FreeTube)

#### Automated Builds (Nightly / Weekly)
Builds are automatically created from changes to our development branch via [GitHub Actions](https://github.com/FreeTubeApp/FreeTube/actions?query=workflow%3ABuild).
Expand All @@ -87,7 +87,7 @@ These builds are maintained by the community. While they should be safe, downlo

* makedeb Package Repository (MPR): [Download](https://mpr.makedeb.org/packages/freetube-bin)

* PortableApps (Windows Only): [Download](https://github.com/rddim/FreeTubePortable/releases) [Source](https://github.com/rddim/FreeTubePortable)
* PortableApps (Windows Only): [Download](https://github.com/rddim/FreeTubePortable/releases) and [Source](https://github.com/rddim/FreeTubePortable)

* Scoop (Windows Only): [Usage](https://github.com/ScoopInstaller/Scoop)

Expand Down
8 changes: 1 addition & 7 deletions _scripts/webpack.renderer.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -134,13 +134,7 @@ const config = {
alias: {
vue$: 'vue/dist/vue.common.js',

// use the web version of linkedom
linkedom$: 'linkedom/worker',

// defaults to the prebundled browser version which causes webpack to error with:
// "Critical dependency: require function is used in a way in which dependencies cannot be statically extracted"
// webpack likes to bundle the dependencies itself, could really have a better error message though
'youtubei.js$': 'youtubei.js/dist/browser.js',
'youtubei.js$': 'youtubei.js/web',
},
extensions: ['.js', '.vue']
},
Expand Down
15 changes: 4 additions & 11 deletions _scripts/webpack.web.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,10 @@ const config = {
path: path.join(__dirname, '../dist/web'),
filename: '[name].js',
},
externals: [
{
electron: '{}'
},
({ request }, callback) => {
if (request.startsWith('youtubei.js')) {
return callback(null, '{}')
}
callback()
}
],
externals: {
electron: '{}',
'youtubei.js': '{}'
},
module: {
rules: [
{
Expand Down
3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,7 @@
"vue-observe-visibility": "^1.0.0",
"vue-router": "^3.6.5",
"vuex": "^3.6.2",
"youtubei.js": "^2.9.0",
"yt-channel-info": "^3.2.1"
"youtubei.js": "^3.1.0"
},
"devDependencies": {
"@babel/core": "^7.21.0",
Expand Down
7 changes: 5 additions & 2 deletions src/renderer/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -430,11 +430,14 @@ export default defineComponent({
}

case 'channel': {
const { channelId, subPath } = result
const { channelId, subPath, url } = result

openInternalPath({
path: `/channel/${channelId}/${subPath}`,
doCreateNewWindow
doCreateNewWindow,
query: {
url
}
})
break
}
Expand Down
43 changes: 25 additions & 18 deletions src/renderer/components/data-settings/data-settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import FtFlexBox from '../ft-flex-box/ft-flex-box.vue'
import FtPrompt from '../ft-prompt/ft-prompt.vue'
import { MAIN_PROFILE_ID } from '../../../constants'

import ytch from 'yt-channel-info'
import { calculateColorLuminance, getRandomColor } from '../../helpers/colors'
import {
copyToClipboard,
Expand All @@ -17,6 +16,7 @@ import {
writeFileFromDialog
} from '../../helpers/utils'
import { invidiousAPICall } from '../../helpers/api/invidious'
import { getLocalChannel } from '../../helpers/api/local'

export default defineComponent({
name: 'DataSettings',
Expand Down Expand Up @@ -967,25 +967,32 @@ export default defineComponent({
})
},

getChannelInfoLocal: function (channelId) {
return new Promise((resolve, reject) => {
ytch.getChannelInfo({ channelId: channelId }).then(async (response) => {
resolve(response)
}).catch((err) => {
console.error(err)
const errorMessage = this.$t('Local API Error (Click to copy)')
showToast(`${errorMessage}: ${err}`, 10000, () => {
copyToClipboard(err)
})
getChannelInfoLocal: async function (channelId) {
try {
const channel = await getLocalChannel(channelId)

if (this.backendFallback && this.backendPreference === 'local') {
showToast(this.$t('Falling back to the Invidious API'))
resolve(this.getChannelInfoInvidious(channelId))
} else {
resolve([])
}
if (channel.alert) {
return undefined
}

return {
author: channel.header.author.name,
authorThumbnails: channel.header.author.thumbnails
}
} catch (err) {
console.error(err)
const errorMessage = this.$t('Local API Error (Click to copy)')
showToast(`${errorMessage}: ${err}`, 10000, () => {
copyToClipboard(err)
})
})

if (this.backendFallback && this.backendPreference === 'local') {
showToast(this.$t('Falling back to the Invidious API'))
return await this.getChannelInfoInvidious(channelId)
} else {
return []
}
}
},

/*
Expand Down
10 changes: 10 additions & 0 deletions src/renderer/components/ft-video-player/ft-video-player.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,16 @@ import { calculateColorLuminance, colors } from '../../helpers/colors'
import { pathExists } from '../../helpers/filesystem'
import { getPicturesPath, showSaveDialog, showToast } from '../../helpers/utils'

// 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 (options.headers?.Range && new URL(options.uri).hostname.endsWith('.googlevideo.com')) {
options.uri += `&range=${options.headers.Range.split('=')[1]}`
delete options.headers.Range
}
}

export default defineComponent({
name: 'FtVideoPlayer',
props: {
Expand Down
8 changes: 5 additions & 3 deletions src/renderer/components/top-nav/top-nav.js
Original file line number Diff line number Diff line change
Expand Up @@ -175,12 +175,14 @@ export default defineComponent({
}

case 'channel': {
const { channelId, idType, subPath } = result
const { channelId, subPath, url } = result

openInternalPath({
path: `/channel/${channelId}/${subPath}`,
query: { idType },
doCreateNewWindow
doCreateNewWindow,
query: {
url
}
})
break
}
Expand Down
31 changes: 29 additions & 2 deletions src/renderer/helpers/api/invidious.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ function getCurrentInstance() {
return store.getters.getCurrentInvidiousInstance
}

export function invidiousAPICall({ resource, id = '', params = {} }) {
export function invidiousAPICall({ resource, id = '', params = {}, doLogError = true }) {
return new Promise((resolve, reject) => {
const requestUrl = getCurrentInstance() + '/api/v1/' + resource + '/' + id + '?' + new URLSearchParams(params).toString()

Expand All @@ -19,12 +19,39 @@ export function invidiousAPICall({ resource, id = '', params = {} }) {
resolve(json)
})
.catch((error) => {
console.error('Invidious API error', requestUrl, error)
if (doLogError) {
console.error('Invidious API error', requestUrl, error)
}
reject(error)
})
})
}

/**
* Gets the channel ID for a channel URL
* used to get the ID for channel usernames and handles
* @param {string} url
*/
export async function invidiousGetChannelId(url) {
try {
const response = await invidiousAPICall({
resource: 'resolveurl',
params: {
url
},
doLogError: false
})

if (response.pageType === 'WEB_PAGE_TYPE_CHANNEL') {
return response.ucid
} else {
return null
}
} catch {
return null
}
}

export async function invidiousGetChannelInfo(channelId) {
return await invidiousAPICall({
resource: 'channels',
Expand Down
Loading

0 comments on commit cd2b314

Please sign in to comment.