Skip to content

Commit

Permalink
Migrate playlists on the watch page to YouTube.js (#2969)
Browse files Browse the repository at this point in the history
  • Loading branch information
absidue committed Dec 16, 2022
1 parent ac509bd commit c912435
Show file tree
Hide file tree
Showing 9 changed files with 46 additions and 81 deletions.
2 changes: 1 addition & 1 deletion _scripts/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ const config = {
'!node_modules/**/*',

// renderer
'node_modules/{miniget,ytpl,ytsr}/**/*',
'node_modules/{miniget,ytsr}/**/*',

'!**/README.md',
'!**/*.js.map',
Expand Down
4 changes: 2 additions & 2 deletions _scripts/webpack.renderer.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ const config = {
path: path.join(__dirname, '../dist'),
filename: '[name].js',
},
// webpack spits out errors while inlining ytpl and ytsr as
// webpack spits out errors while inlining ytsr as
// they dynamically import their package.json file to extract the bug report URL
// the error: "Critical dependency: the request of a dependency is an expression"
externals: ['ytpl', 'ytsr'],
externals: ['ytsr'],
module: {
rules: [
{
Expand Down
1 change: 0 additions & 1 deletion _scripts/webpack.web.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ const config = {
externals: {
electron: '{}',
'youtubei.js': '{}',
ytpl: '{}',
ytsr: '{}'
},
module: {
Expand Down
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,6 @@
"yt-channel-info": "^3.2.1",
"yt-dash-manifest-generator": "1.1.0",
"ytdl-core": "https://github.com/absidue/node-ytdl-core#fix-likes-extraction",
"ytpl": "^2.3.0",
"ytsr": "^3.8.0"
},
"devDependencies": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import FtLoader from '../ft-loader/ft-loader.vue'
import FtCard from '../ft-card/ft-card.vue'
import FtListVideo from '../ft-list-video/ft-list-video.vue'
import { copyToClipboard, showToast } from '../../helpers/utils'
import { getLocalPlaylist, parseLocalPlaylistVideo } from '../../helpers/api/local'

export default Vue.extend({
name: 'WatchVideoPlaylist',
Expand Down Expand Up @@ -241,36 +242,31 @@ export default Vue.extend({
}
},

getPlaylistInformationLocal: function () {
getPlaylistInformationLocal: async function () {
this.isLoading = true

this.ytGetPlaylistInfo(this.playlistId).then((result) => {
this.playlistTitle = result.title
this.playlistItems = result.items
this.videoCount = result.estimatedItemCount
this.channelName = result.author.name
this.channelThumbnail = result.author.bestAvatar.url
this.channelId = result.author.channelID

this.playlistItems = result.items.filter((video) => {
return !(video.title === '[Private video]' || video.title === '[Deleted video]')
}).map((video) => {
if (typeof video.author !== 'undefined') {
const channelName = video.author.name
const channelId = video.author.channelID
video.author = channelName
video.authorId = channelId
} else {
video.author = ''
video.authorId = ''
}
video.videoId = video.id
video.lengthSeconds = video.duration
return video
})
try {
let playlist = await getLocalPlaylist(this.playlistId)

this.playlistTitle = playlist.info.title
this.videoCount = playlist.info.total_items
this.channelName = playlist.info.author?.name
this.channelThumbnail = playlist.info.author?.best_thumbnail?.url
this.channelId = playlist.info.author?.id

const videos = playlist.items.map(parseLocalPlaylistVideo)

while (playlist.has_continuation) {
playlist = await playlist.getContinuation()

const parsedVideos = playlist.items.map(parseLocalPlaylistVideo)
videos.push(...parsedVideos)
}

this.playlistItems = videos

this.isLoading = false
}).catch((err) => {
} catch (err) {
console.error(err)
const errorMessage = this.$t('Local API Error (Click to copy)')
showToast(`${errorMessage}: ${err}`, 10000, () => {
Expand All @@ -282,7 +278,7 @@ export default Vue.extend({
} else {
this.isLoading = false
}
})
}
},

getPlaylistInformationInvidious: function () {
Expand Down Expand Up @@ -339,7 +335,6 @@ export default Vue.extend({
},

...mapActions([
'ytGetPlaylistInfo',
'invidiousGetPlaylistInfo'
])
}
Expand Down
17 changes: 17 additions & 0 deletions src/renderer/helpers/api/local.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,20 @@ export async function getLocalPlaylist(id) {
const innertube = await createInnertube()
return await innertube.getPlaylist(id)
}

/**
* @typedef {import('youtubei.js/dist/src/parser/classes/PlaylistVideo').default} PlaylistVideo
*/

/**
* @param {PlaylistVideo} video
*/
export function parseLocalPlaylistVideo(video) {
return {
videoId: video.id,
title: video.title.text,
author: video.author.name,
authorId: video.author.id,
lengthSeconds: isNaN(video.duration.seconds) ? '' : video.duration.seconds
}
}
28 changes: 0 additions & 28 deletions src/renderer/store/modules/ytdl.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
import ytdl from 'ytdl-core'
import ytsr from 'ytsr'
import ytpl from 'ytpl'

import { SocksProxyAgent } from 'socks-proxy-agent'
import { HttpsProxyAgent } from 'https-proxy-agent'
import { HttpProxyAgent } from 'http-proxy-agent'

import i18n from '../../i18n/index'
import { searchFiltersMatch } from '../../helpers/utils'

const state = {
Expand Down Expand Up @@ -193,32 +191,6 @@ const actions = {
})
},

ytGetPlaylistInfo ({ rootState }, playlistId) {
return new Promise((resolve, reject) => {
let agent = null
const settings = rootState.settings

if (settings.useProxy) {
agent = createProxyAgent(settings.proxyProtocol, settings.proxyHostname, settings.proxyPort)
}
let locale = i18n.locale.replace('_', '-')

if (locale === 'nn') {
locale = 'no'
}

ytpl(playlistId, {
hl: locale,
limit: Infinity,
requestOptions: { agent }
}).then((result) => {
resolve(result)
}).catch((err) => {
reject(err)
})
})
},

ytGetVideoInformation ({ rootState }, videoId) {
return new Promise((resolve, reject) => {
let agent = null
Expand Down
16 changes: 3 additions & 13 deletions src/renderer/views/Playlist/Playlist.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import FtListVideo from '../../components/ft-list-video/ft-list-video.vue'
import FtFlexBox from '../../components/ft-flex-box/ft-flex-box.vue'
import FtButton from '../../components/ft-button/ft-button.vue'
import i18n from '../../i18n/index'
import { getLocalPlaylist } from '../../helpers/api/local'
import { getLocalPlaylist, parseLocalPlaylistVideo } from '../../helpers/api/local'
import { extractNumberFromString } from '../../helpers/utils'

export default Vue.extend({
Expand Down Expand Up @@ -90,7 +90,7 @@ export default Vue.extend({
channelId: this.infoData.channelId
})

this.playlistItems = result.items.map(this.parseVideoLocal)
this.playlistItems = result.items.map(parseLocalPlaylistVideo)

if (result.has_continuation) {
this.continuationData = result
Expand All @@ -108,16 +108,6 @@ export default Vue.extend({
})
},

parseVideoLocal: function (video) {
return {
videoId: video.id,
title: video.title.text,
author: video.author.name,
authorId: video.author.id,
lengthSeconds: isNaN(video.duration.seconds) ? '' : video.duration.seconds
}
},

getPlaylistInvidious: function () {
this.isLoading = true

Expand Down Expand Up @@ -179,7 +169,7 @@ export default Vue.extend({
this.isLoadingMore = true

this.continuationData.getContinuation().then((result) => {
const parsedVideos = result.items.map(this.parseVideoLocal)
const parsedVideos = result.items.map(parseLocalPlaylistVideo)
this.playlistItems = this.playlistItems.concat(parsedVideos)

if (result.has_continuation) {
Expand Down
7 changes: 0 additions & 7 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -8710,13 +8710,6 @@ ytdl-core@^3.2.2:
miniget "^4.2.2"
sax "^1.1.3"

ytpl@^2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/ytpl/-/ytpl-2.3.0.tgz#74633b6e582e22ff03e409dfb65d200c1a4ca0d2"
integrity sha512-Cfw2rxq3PFK6qgWr2Z8gsRefVahEzbn9XEuiJldqdXHE6GhO7kTfEvbZKdfXing1SmgW635uJ/UL2g8r0fvu2Q==
dependencies:
miniget "^4.2.2"

ytsr@^3.8.0:
version "3.8.0"
resolved "https://registry.yarnpkg.com/ytsr/-/ytsr-3.8.0.tgz#49a8e5dc413f41515fc3d79d93ee3e073d10e772"
Expand Down

0 comments on commit c912435

Please sign in to comment.