add piped playlist support

This commit is contained in:
chunky programmer 2023-05-08 19:51:37 -04:00 committed by Chunky programmer
parent 5ef7627195
commit 17c7510f90
2 changed files with 78 additions and 4 deletions

View File

@ -1,8 +1,12 @@
import store from '../../store/index'
import { isNullOrEmpty, toLocalePublicationString } from '../utils'
const apiUrl = 'https://pipedapi.kavin.rocks'
function getCurrentInstance() {
return store.getters.getCurrentPipedInstance
}
export async function pipedRequest({ resource, id = '', params = {}, doLogError = true, subResource = '' }) {
const requestUrl = apiUrl + '/' + resource + '/' + id + (!isNullOrEmpty(subResource) ? `/${subResource}` : '') + '?' + new URLSearchParams(params).toString()
const requestUrl = getCurrentInstance() + '/' + resource + '/' + id + (!isNullOrEmpty(subResource) ? `/${subResource}` : '') + '?' + new URLSearchParams(params).toString()
return await fetch(requestUrl)
.then((response) => response.json())
.then((json) => {
@ -67,3 +71,54 @@ function parsePipedComments(comments) {
}
})
}
export async function getPipedPlaylist(playlistId) {
const pList = await pipedRequest({ resource: 'playlists', id: playlistId })
console.error(pList)
const parsedVideos = parsePipedVideos(pList.relatedStreams)
return {
playlist: parsePipedPlaylist(playlistId, pList, parsedVideos),
videos: parsedVideos
}
}
export function getPipedUrlInfo(url) {
const regex = /^(?<baseUrl>.*)\/(?<imageProtocol>vi|ytc)\/(?<resource>[^?]*).*host=(?<host>[^&]*)/
return url.match(regex).groups
}
export function pipedImageToYouTube(url) {
const { host, imageProtocol, resource } = getPipedUrlInfo(url)
return `https://${host}/${imageProtocol}/${resource}`
}
function parsePipedPlaylist(playlistId, result, parsedVideos) {
return {
id: playlistId,
title: result.name,
description: '',
firstVideoId: parsedVideos[0].videoId,
viewCount: null,
videoCount: result.videos,
channelName: result.uploader,
channelThumbnail: result.uploaderAvatar,
channelId: result.uploaderUrl.replace('/channel/', ''),
infoSource: 'piped'
}
}
function parsePipedVideos(videoList) {
return videoList.map(video => {
return {
videoId: video.url.replace('/watch?v=', ''),
title: video.title,
author: video.uploaderName,
authorId: video.uploaderUrl.replace('/channel/', ''),
lengthSeconds: video.duration,
description: video.shortDescription,
uploaded: video.uploaded, // uploaded time stamp
viewCount: video.views,
thumbnail: video.thumbnail
}
})
}

View File

@ -9,7 +9,7 @@ import FtButton from '../../components/ft-button/ft-button.vue'
import { getLocalPlaylist, parseLocalPlaylistVideo } from '../../helpers/api/local'
import { extractNumberFromString } from '../../helpers/utils'
import { invidiousGetPlaylistInfo, youtubeImageUrlToInvidious } from '../../helpers/api/invidious'
import { getPipedPlaylist, pipedImageToYouTube } from '../../helpers/api/piped'
export default defineComponent({
name: 'Playlist',
components: {
@ -45,7 +45,8 @@ export default defineComponent({
},
computed: {
backendPreference: function () {
return this.$store.getters.getBackendPreference
return 'piped'
// return this.$store.getters.getBackendPreference
},
backendFallback: function () {
return this.$store.getters.getBackendFallback
@ -77,6 +78,9 @@ export default defineComponent({
case 'invidious':
this.getPlaylistInvidious()
break
case 'piped':
this.getPlaylistPiped()
break
}
},
getPlaylistLocal: function () {
@ -162,6 +166,21 @@ export default defineComponent({
})
},
getPlaylistPiped: async function () {
this.isLoading = true
const { playlist, videos } = await getPipedPlaylist(this.playlistId)
this.infoData = playlist
this.playlistItems = this.playlistItems.concat(videos)
this.updateSubscriptionDetails({
channelThumbnailUrl: pipedImageToYouTube(playlist.channelThumbnail),
channelName: playlist.channelName,
channelId: playlist.channelId
})
this.isLoading = false
},
getNextPage: function () {
switch (this.infoData.infoSource) {
case 'local':