diff --git a/controller/video.js b/controller/video.js index 687a015..b2197d2 100644 --- a/controller/video.js +++ b/controller/video.js @@ -33,9 +33,8 @@ exports.getVideo = async (req, res) => { } exports.getChannel = async (req, res) => { - const instance = await metadata.getInstance() - const videos = await metadata.getChannelVideos(instance, req.params.id) - const channel = await metadata.getChannel(instance, req.params.id) + const videos = await metadata.getChannelVideos(req.params.id) + const channel = await metadata.getChannel(req.params.id) if (videos.error) return res.json({ error: '404' }) const archived = await prisma.videos.findMany({ @@ -66,7 +65,7 @@ exports.getChannel = async (req, res) => { const index = allVideos.findIndex(o => o.id == v.id) allVideos[index] = v } else { - const live = await metadata.getVideoMetadata(instance, v.id) + const live = await metadata.getVideoMetadata(v.id) allVideos.push({ ...v, @@ -86,8 +85,7 @@ exports.getChannel = async (req, res) => { } exports.getPlaylist = async (req, res) => { - const instance = await metadata.getInstance() - const playlist = await metadata.getPlaylistVideos(instance, req.params.id) + const playlist = await metadata.getPlaylistVideos(req.params.id) if (playlist.error) return res.json({ error: '404' }) const playlistArchived = await prisma.videos.findMany({ @@ -118,7 +116,7 @@ exports.getPlaylist = async (req, res) => { const index = allVideos.findIndex(o => o.id == v.id) allVideos[index] = v } else { - const live = await metadata.getVideoMetadata(instance, v.id) + const live = await metadata.getVideoMetadata(v.id) allVideos.push({ ...v, diff --git a/controller/websocket.js b/controller/websocket.js index 82ab9bd..703eea5 100644 --- a/controller/websocket.js +++ b/controller/websocket.js @@ -110,8 +110,7 @@ exports.playlist = async (ws, req) => { }) async function startDownloading() { - const instance = await metadata.getInstance() - const playlist = await metadata.getPlaylistVideos(instance, playlistId) + const playlist = await metadata.getPlaylistVideos(playlistId) for (video of playlist.relatedStreams) { const id = video.url.match(/[?&]v=([^&]+)/)[1] @@ -200,8 +199,7 @@ exports.channel = async (ws, req) => { }) async function startDownloading() { - const instance = await metadata.getInstance() - const videos = await metadata.getChannelVideos(instance, channelId) + const videos = await metadata.getChannelVideos(channelId) for (video of videos) { const id = video.url.match(/[?&]v=([^&]+)/)[1] diff --git a/utils/auto.js b/utils/auto.js index 78cd192..7a58dce 100644 --- a/utils/auto.js +++ b/utils/auto.js @@ -22,8 +22,7 @@ async function handleCheck() { async function handleDownload(channelId) { logger.info({ message: `Checking ${channelId} for new videos...` }) - const instance = await metadata.getInstance() - const videos = await metadata.getChannelVideos(instance, channelId) + const videos = await metadata.getChannelVideos(channelId) for (video of videos) { const id = video.url.match(/[?&]v=([^&]+)/)[1] diff --git a/utils/metadata.js b/utils/metadata.js index 020f4ff..38c6a11 100644 --- a/utils/metadata.js +++ b/utils/metadata.js @@ -1,66 +1,87 @@ const fetch = require('node-fetch') async function getInstance() { + const instances = await (await fetch('https://piped-instances.kavin.rocks/')).json() + return (instances[Math.floor(Math.random() * instances.length)]).api_url +} + +async function getVideoMetadata(id) { for (let i = 0; i < 5; i++) { - const instance = await actuallyGettingInstance() - if (instance) return instance + const video = await actualRequest() + if (video) return video } - async function actuallyGettingInstance() { - const instance = await getRandomInstance() - const test = await testInstance(instance) - if (test) return instance - else { + async function actualRequest() { + try { + const instance = await getInstance() + const json = await (await fetch(`${instance}/streams/${id}`)).json() + return json + } catch (e) { return false } } +} - async function getRandomInstance() { - const instances = await (await fetch('https://piped-instances.kavin.rocks/')).json() - const list = instances.filter(i => !i.cdn) - return (list[Math.floor(Math.random() * list.length)]).api_url +async function getChannel(id) { + for (let i = 0; i < 5; i++) { + const channel = await actualRequest() + if (channel) return channel } - async function testInstance(instance) { + async function actualRequest() { try { - await (await fetch(`${instance}/streams/WDogskpmM7M`)).json() - return true + const instance = await getInstance() + const json = await (await fetch(`${instance}/channel/${id}`)).json() + return json } catch (e) { - return false + return false } } } -async function getVideoMetadata(instance, id) { - const json = await (await fetch(`${instance}/streams/${id}`)).json() - return json -} - -async function getChannel(instance, id) { - const json = await (await fetch(`${instance}/channel/${id}`)).json() - return json -} - async function getChannelVideos(instance, id) { - return new Promise(async (resolve, reject) => { - const videos = [] - const json = await (await fetch(`${instance}/channel/${id}`)).json() - videos.push(...json.relatedStreams) - if (json.nextpage) await getNextPage(json.nextpage) - else resolve(videos) - - async function getNextPage(payload) { - const page = await (await fetch(`${instance}/nextpage/channel/${id}?nextpage=${encodeURIComponent(payload)}`)).json() - videos.push(...page.relatedStreams) - if (page.nextpage) await getNextPage(page.nextpage) - else resolve(videos) + for (let i = 0; i < 5; i++) { + const videos = await actualRequest() + if (videos) return videos + } + + async function actualRequest() { + try { + return new Promise(async (resolve, reject) => { + const videos = [] + const json = await (await fetch(`${instance}/channel/${id}`)).json() + videos.push(...json.relatedStreams) + if (json.nextpage) await getNextPage(json.nextpage) + else resolve(videos) + + async function getNextPage(payload) { + const page = await (await fetch(`${instance}/nextpage/channel/${id}?nextpage=${encodeURIComponent(payload)}`)).json() + videos.push(...page.relatedStreams) + if (page.nextpage) await getNextPage(page.nextpage) + else resolve(videos) + } + }) + } catch (e) { + return false } - }) + } } -async function getPlaylistVideos(instance, id) { - const json = await (await fetch(`${instance}/playlists/${id}`)).json() - return json +async function getPlaylistVideos(id) { + for (let i = 0; i < 5; i++) { + const playlists = await actualRequest() + if (playlists) return playlists + } + + async function actualRequest() { + try { + const instance = await getInstance() + const json = await (await fetch(`${instance}/playlists/${id}`)).json() + return json + } catch (e) { + return false + } + } } module.exports = { getInstance, getVideoMetadata, getChannel, getChannelVideos, getPlaylistVideos } \ No newline at end of file diff --git a/utils/websocket.js b/utils/websocket.js index a9ed6d9..c062865 100644 --- a/utils/websocket.js +++ b/utils/websocket.js @@ -5,8 +5,7 @@ const metadata = require('./metadata.js') const upload = require('./upload.js') async function createDatabaseVideo(id, videoUrl, playlistId) { - const instance = await metadata.getInstance() - const data = await metadata.getVideoMetadata(instance, id) + const data = await metadata.getVideoMetadata(id) const uploaderAvatar = await upload.uploadImage((data.uploaderUrl).replace('/channel/', ''), data.uploaderAvatar) const thumbnailUrl = await upload.uploadImage(id, data.thumbnailUrl)