diff --git a/package.json b/package.json
index fb0de3ae41601..10f8bb68127cf 100644
--- a/package.json
+++ b/package.json
@@ -2,7 +2,7 @@
"name": "freetube",
"productName": "FreeTube",
"description": "A private YouTube client",
- "version": "0.18.0",
+ "version": "0.19.0",
"license": "AGPL-3.0-or-later",
"main": "./dist/main.js",
"private": true,
@@ -78,7 +78,7 @@
"vue-router": "^3.6.5",
"vue-tiny-slider": "^0.1.39",
"vuex": "^3.6.2",
- "youtubei.js": "^5.8.0"
+ "youtubei.js": "^6.0.0"
},
"devDependencies": {
"@babel/core": "^7.22.10",
diff --git a/src/renderer/components/ft-list-video/ft-list-video.vue b/src/renderer/components/ft-list-video/ft-list-video.vue
index 3bc69ffb55318..70cdecbfa35a4 100644
--- a/src/renderer/components/ft-list-video/ft-list-video.vue
+++ b/src/renderer/components/ft-list-video/ft-list-video.vue
@@ -105,7 +105,9 @@
query: playlistIdFinal ? {playlistId: playlistIdFinal} : {}
}"
>
-
{{ displayTitle }}
+
+ {{ displayTitle }}
+
this.scrollToCurrentVideo())
}
},
+ playlistId: function (newVal, oldVal) {
+ if (oldVal !== newVal) {
+ if (!process.env.IS_ELECTRON || this.backendPreference === 'invidious') {
+ this.getPlaylistInformationInvidious()
+ } else {
+ this.getPlaylistInformationLocal()
+ }
+ }
+ }
},
mounted: function () {
const cachedPlaylist = this.$store.getters.getCachedPlaylist
@@ -356,8 +365,19 @@ export default defineComponent({
try {
let playlist = await getLocalPlaylist(this.playlistId)
+ let channelName
+
+ if (playlist.info.author) {
+ channelName = playlist.info.author.name
+ } else {
+ const subtitle = playlist.info.subtitle.toString()
+
+ const index = subtitle.lastIndexOf('•')
+ channelName = subtitle.substring(0, index).trim()
+ }
+
this.playlistTitle = playlist.info.title
- this.channelName = playlist.info.author?.name
+ this.channelName = channelName
this.channelId = playlist.info.author?.id
const videos = playlist.items.map(parseLocalPlaylistVideo)
diff --git a/src/renderer/components/watch-video-playlist/watch-video-playlist.vue b/src/renderer/components/watch-video-playlist/watch-video-playlist.vue
index d3053c621ce9c..c0f9d5ae61bda 100644
--- a/src/renderer/components/watch-video-playlist/watch-video-playlist.vue
+++ b/src/renderer/components/watch-video-playlist/watch-video-playlist.vue
@@ -14,13 +14,23 @@
{{ playlistTitle }}
-
- {{ channelName }} -
-
+
+ {{ channelName }} -
+
+
+ {{ channelName }} -
+
+
diff --git a/src/renderer/views/Hashtag/Hashtag.js b/src/renderer/views/Hashtag/Hashtag.js
index 5001d60476ba5..61d0b8bead220 100644
--- a/src/renderer/views/Hashtag/Hashtag.js
+++ b/src/renderer/views/Hashtag/Hashtag.js
@@ -97,12 +97,26 @@ export default defineComponent({
getLocalHashtag: async function(hashtag) {
try {
const hashtagData = await getHashtagLocal(hashtag)
- this.hashtag = hashtagData.header.hashtag
- this.videos = hashtagData.contents.contents.filter(item =>
- item.type !== 'ContinuationItem'
- ).map(item =>
- parseLocalListVideo(item.content)
- )
+
+ const header = hashtagData.header
+ if (header) {
+ switch (header.type) {
+ case 'HashtagHeader':
+ this.hashtag = header.hashtag.toString()
+ break
+ case 'PageHeader':
+ this.hashtag = header.content.title.text
+ break
+ default:
+ console.error(`Unknown hashtag header type: ${header.type}, falling back to query parameter.`)
+ this.hashtag = `#${hashtag}`
+ }
+ } else {
+ console.error(' Hashtag header missing, probably a layout change, falling back to query parameter.')
+ this.hashtag = `#${hashtag}`
+ }
+
+ this.videos = hashtagData.videos.map(parseLocalListVideo)
this.apiUsed = 'local'
this.hashtagContinuationData = hashtagData.has_continuation ? hashtagData : null
this.isLoading = false
@@ -124,12 +138,8 @@ export default defineComponent({
getLocalHashtagMore: async function() {
try {
- const continuation = await this.hashtagContinuationData.getContinuationData()
- const newVideos = continuation.on_response_received_actions[0].contents.filter(item =>
- item.type !== 'ContinuationItem'
- ).map(item =>
- parseLocalListVideo(item.content)
- )
+ const continuation = await this.hashtagContinuationData.getContinuation()
+ const newVideos = continuation.videos.map(parseLocalListVideo)
this.hashtagContinuationData = continuation.has_continuation ? continuation : null
this.videos = this.videos.concat(newVideos)
} catch (error) {
diff --git a/src/renderer/views/Watch/Watch.js b/src/renderer/views/Watch/Watch.js
index d11fc367c2cb7..e11ae301bc9ec 100644
--- a/src/renderer/views/Watch/Watch.js
+++ b/src/renderer/views/Watch/Watch.js
@@ -608,7 +608,14 @@ export default defineComponent({
/** @type {import('youtubei.js').Misc.Format[][]} */
const sourceLists = []
- audioFormats.forEach(format => {
+ for (const format of audioFormats) {
+ // Some videos with multiple audio tracks, have a broken one, that doesn't have any audio track information
+ // It seems to be the same as default audio track but broken
+ // At the time of writing, this video has a broken audio track: https://youtu.be/UJeSWbR6W04
+ if (!format.audio_track) {
+ continue
+ }
+
const index = ids.indexOf(format.audio_track.id)
if (index === -1) {
ids.push(format.audio_track.id)
@@ -640,7 +647,7 @@ export default defineComponent({
} else {
sourceLists[index].push(format)
}
- })
+ }
for (let i = 0; i < audioTracks.length; i++) {
audioTracks[i].sourceList = this.createLocalAudioSourceList(sourceLists[i])
diff --git a/static/locales/bg.yaml b/static/locales/bg.yaml
index ede0e5875fd9a..3353d0c225e74 100644
--- a/static/locales/bg.yaml
+++ b/static/locales/bg.yaml
@@ -601,6 +601,7 @@ Profile:
#On Channel Page
Profile Filter: Профилен филтър
Profile Settings: Настройки на профил
+ Toggle Profile List: Превключване на списъка с профили
Channel:
Subscriber: 'Абонат'
Subscribers: 'Абонати'
diff --git a/static/locales/de-DE.yaml b/static/locales/de-DE.yaml
index 9d5eb1a67f4c7..ee4e2a070919e 100644
--- a/static/locales/de-DE.yaml
+++ b/static/locales/de-DE.yaml
@@ -926,6 +926,7 @@ Profile:
Profile Select: Profilauswahl
Profile Filter: Profilfilter
Profile Settings: Profileinstellungen
+ Toggle Profile List: Profilliste umschalten
The playlist has been reversed: Die Wiedergabeliste wurde umgedreht
A new blog is now available, {blogTitle}. Click to view more: Ein neuer Blogeintrag
ist verfügbar, {blogTitle}. Um ihn zu öffnen klicken
diff --git a/static/locales/sv.yaml b/static/locales/sv.yaml
index f710b316ed2fd..150ce8d935172 100644
--- a/static/locales/sv.yaml
+++ b/static/locales/sv.yaml
@@ -97,7 +97,7 @@ Subscriptions:
Disabled Automatic Fetching: Du har avaktiverat automatisk prenumerationshämtning.
Uppdatera prenumerationerna för att se dem här.
Empty Channels: Dina prenumererade kanaler har inga filmer.
- Subscriptions Tabs: Prenumerations Flik
+ Subscriptions Tabs: Prenumeration Flik
All Subscription Tabs Hidden: Alla prenumerationsflikar är dolda. För att se innehåll
här, vänligen avdölj några flikar i avsnittet "{subsection}" i "{settingsSection}".
Trending:
@@ -471,7 +471,7 @@ Settings:
Download Settings:
Ask Download Path: Välj nerladdningsmapp varje gång
Download Settings: Nerladdningsinställningar
- Choose Path: Välj mapp
+ Choose Path: Välj Sökväg
Download in app: Ladda ner i appen
Download Behavior: Nerladdningsalternativ
Open in web browser: Öppna i webbläsare
@@ -585,6 +585,7 @@ Profile:
#On Channel Page
Profile Filter: Profilfilter
Profile Settings: Profilinställningar
+ Toggle Profile List: Aktivera Profillista
Channel:
Subscriber: 'Prenumerant'
Subscribers: 'Prenumeranter'
@@ -646,8 +647,7 @@ Channel:
inga släpp
Podcasts:
Podcasts: Podcasts
- This channel does not currently have any podcasts: Den här kanalen har för närvarande
- inga podcasts
+ This channel does not currently have any podcasts: Den här kanalen har inga podcasts
Video:
Mark As Watched: 'Markera som sedd'
Remove From History: 'Ta bort från historik'
@@ -830,7 +830,7 @@ Share:
Mini Player: 'Minispelare'
Comments:
Comments: 'Kommentarer'
- Click to View Comments: 'Visa kommentarer'
+ Click to View Comments: 'Klicka för att Visa kommentarer'
Getting comment replies, please wait: 'Hämtar kommentar svar, vänligen vänta'
There are no more comments for this video: 'Det finns inga fler kommentarer för
videon'
diff --git a/yarn.lock b/yarn.lock
index c38007dc9514a..e2afc7cfcd178 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2983,11 +2983,6 @@ csso@^5.0.5:
dependencies:
css-tree "~2.2.0"
-cssom@^0.5.0:
- version "0.5.0"
- resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.5.0.tgz#d254fa92cd8b6fbd83811b9fbaed34663cc17c36"
- integrity sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==
-
csstype@^3.1.0:
version "3.1.1"
resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.1.tgz#841b532c45c758ee546a11d5bd7b7b473c8c30b9"
@@ -3405,7 +3400,7 @@ entities@^2.0.0:
resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55"
integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==
-entities@^4.2.0, entities@^4.3.0:
+entities@^4.2.0:
version "4.4.0"
resolved "https://registry.yarnpkg.com/entities/-/entities-4.4.0.tgz#97bdaba170339446495e653cfd2db78962900174"
integrity sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==
@@ -4580,11 +4575,6 @@ html-entities@^2.3.2:
resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-2.3.3.tgz#117d7626bece327fc8baace8868fa6f5ef856e46"
integrity sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA==
-html-escaper@^3.0.3:
- version "3.0.3"
- resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-3.0.3.tgz#4d336674652beb1dcbc29ef6b6ba7f6be6fdfed6"
- integrity sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ==
-
html-minifier-terser@^6.0.2:
version "6.1.0"
resolved "https://registry.yarnpkg.com/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz#bfc818934cc07918f6b3669f5774ecdfd48f32ab"
@@ -4624,16 +4614,6 @@ htmlparser2@^6.1.0:
domutils "^2.5.2"
entities "^2.0.0"
-htmlparser2@^8.0.1:
- version "8.0.1"
- resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-8.0.1.tgz#abaa985474fcefe269bc761a779b544d7196d010"
- integrity sha512-4lVbmc1diZC7GUJQtRQ5yBAeUCL1exyMwmForWkRLnwyzWBFxN633SALPMGYaWZvKe9j1pRZJpauvmxENSp/EA==
- dependencies:
- domelementtype "^2.3.0"
- domhandler "^5.0.2"
- domutils "^3.0.1"
- entities "^4.3.0"
-
http-cache-semantics@^4.0.0:
version "4.1.1"
resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz#abe02fcb2985460bf0323be664436ec3476a6d5a"
@@ -5459,17 +5439,6 @@ lines-and-columns@^1.1.6:
resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632"
integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==
-linkedom@^0.14.12:
- version "0.14.19"
- resolved "https://registry.yarnpkg.com/linkedom/-/linkedom-0.14.19.tgz#a8e9b91af26d5c631b5b3d21614cef1db8a56fb7"
- integrity sha512-sFNkQZlKBWpEaAcbsDIghTLE0hHbyvS6dZuM7IH+KTM09GaQ772PtDZAuFlN0oFgyAjUj8XS9FpoWSLmBjl8MA==
- dependencies:
- css-select "^5.1.0"
- cssom "^0.5.0"
- html-escaper "^3.0.3"
- htmlparser2 "^8.0.1"
- uhyphen "^0.1.0"
-
load-json-file@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b"
@@ -8053,11 +8022,6 @@ typescript@^4.0.2:
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a"
integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==
-uhyphen@^0.1.0:
- version "0.1.0"
- resolved "https://registry.yarnpkg.com/uhyphen/-/uhyphen-0.1.0.tgz#3cc22afa790daa802b9f6789f3583108d5b4a08c"
- integrity sha512-o0QVGuFg24FK765Qdd5kk0zU/U4dEsCtN/GSiwNI9i8xsSVtjIAOdTaVhLwZ1nrbWxFVMxNDDl+9fednsOMsBw==
-
unbox-primitive@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e"
@@ -8715,12 +8679,11 @@ yocto-queue@^1.0.0:
resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-1.0.0.tgz#7f816433fb2cbc511ec8bf7d263c3b58a1a3c251"
integrity sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==
-youtubei.js@^5.8.0:
- version "5.8.0"
- resolved "https://registry.yarnpkg.com/youtubei.js/-/youtubei.js-5.8.0.tgz#4c6dc898b6a2c6cbf91f95932be18e981e394e2d"
- integrity sha512-xMQxbhy0TMpLvJnGbLnqAE9RhiLCwBuVrsTyVd0ZFX6o98fmJmddcE1qeRIagNGNr16BmofqtsbGXIfpZprFhA==
+youtubei.js@^6.0.0:
+ version "6.0.0"
+ resolved "https://registry.yarnpkg.com/youtubei.js/-/youtubei.js-6.0.0.tgz#545b8744a826ef7bfdb21a7c930950e784a85659"
+ integrity sha512-GGQpSfBGlqcDav4UtMoUehJTuHjLOZBynLFJBSIRZVXFWRzPCIl/LF2GTOZnZJfutmi62VaXvjiz4pGvCJO5bg==
dependencies:
jintr "^1.1.0"
- linkedom "^0.14.12"
tslib "^2.5.0"
undici "^5.19.1"