RSS: parallel-fetch the stream urls
## Issue Users are seeing timeout with the RSS calls. But oddly, odysee.com is significantly slower than the dev instances.
This commit is contained in:
parent
7504cf07b3
commit
b8cf1a6c4c
1 changed files with 30 additions and 7 deletions
|
@ -62,37 +62,54 @@ function encodeWithSpecialCharEncode(string) {
|
|||
return encodeURIComponent(string).replace(/'/g, '%27').replace(/\(/g, '%28').replace(/\)/g, '%29');
|
||||
}
|
||||
|
||||
async function generateEnclosureForClaimContent(claim) {
|
||||
/**
|
||||
* Returns an array of stream-url promise results corresponding to the same
|
||||
* order as the given 'claims' array, or null if there is an error.
|
||||
*
|
||||
* Clients must check the promise 'status' for each entry, as some could be a
|
||||
* failed fetch (i.e. 'rejected').
|
||||
*
|
||||
* @param claims Array of freaking claims.
|
||||
* @returns {Array<{status, value}> | null}
|
||||
*/
|
||||
async function fetchStreamUrls(claims) {
|
||||
return Promise.allSettled(claims.map((c) => fetchStreamUrl(c.name, c.claim_id)))
|
||||
.then((results) => results)
|
||||
.catch(() => null);
|
||||
}
|
||||
|
||||
async function generateEnclosureForClaimContent(claim, streamUrl) {
|
||||
const value = claim.value;
|
||||
if (!value || !value.stream_type) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const fileExt = value.source && value.source.media_type && '.' + Mime.extension(value.source.media_type);
|
||||
|
||||
switch (value.stream_type) {
|
||||
case 'video':
|
||||
return {
|
||||
url: (await fetchStreamUrl(claim.name, claim.claim_id)).replace('/v4/', '/v3/') + (fileExt || '.mp4'), // v3 = mp4 always, v4 may redirect to m3u8
|
||||
url: streamUrl.replace('/v4/', '/v3/') + (fileExt || '.mp4'), // v3 = mp4 always, v4 may redirect to m3u8
|
||||
type: (value.source && value.source.media_type) || 'video/mp4',
|
||||
size: (value.source && value.source.size) || 0, // Per spec, 0 is a valid fallback.
|
||||
};
|
||||
|
||||
case 'audio':
|
||||
return {
|
||||
url: (await fetchStreamUrl(claim.name, claim.claim_id)) + ((fileExt === '.mpga' ? '.mp3' : fileExt) || '.mp3'),
|
||||
url: streamUrl + ((fileExt === '.mpga' ? '.mp3' : fileExt) || '.mp3'),
|
||||
type: (value.source && value.source.media_type) || 'audio/mpeg',
|
||||
size: (value.source && value.source.size) || 0, // Per spec, 0 is a valid fallback.
|
||||
};
|
||||
case 'image':
|
||||
return {
|
||||
url: (await fetchStreamUrl(claim.name, claim.claim_id)) + (fileExt || '.jpeg'),
|
||||
url: streamUrl + (fileExt || '.jpeg'),
|
||||
type: (value.source && value.source.media_type) || 'image/jpeg',
|
||||
size: (value.source && value.source.size) || 0, // Per spec, 0 is a valid fallback.
|
||||
};
|
||||
case 'document':
|
||||
case 'software':
|
||||
return {
|
||||
url: await fetchStreamUrl(claim.name, claim.claim_id),
|
||||
url: streamUrl,
|
||||
type: (value.source && value.source.media_type) || undefined,
|
||||
size: (value.source && value.source.size) || 0, // Per spec, 0 is a valid fallback.
|
||||
};
|
||||
|
@ -174,7 +191,7 @@ const getItunesCategory = (claim) => {
|
|||
// "Note: Although you can specify more than one category and subcategory
|
||||
// in your RSS feed, Apple Podcasts only recognizes the first category and
|
||||
// subcategory."
|
||||
// --> The only parse the first found tag.
|
||||
// --> They only parse the first found tag.
|
||||
return itunesCategory.replace('&', '&');
|
||||
}
|
||||
}
|
||||
|
@ -244,6 +261,9 @@ async function generateFeed(feedLink, channelClaim, claimsInChannel) {
|
|||
],
|
||||
});
|
||||
|
||||
// --- Parallel pre-fetch of stream url ---
|
||||
const streamUrls = await fetchStreamUrls(claimsInChannel);
|
||||
|
||||
// --- Content ---
|
||||
for (let i = 0; i < claimsInChannel.length; ++i) {
|
||||
const c = claimsInChannel[i];
|
||||
|
@ -258,6 +278,9 @@ async function generateFeed(feedLink, channelClaim, claimsInChannel) {
|
|||
const date =
|
||||
c.value && c.value.release_time ? c.value.release_time * 1000 : c.meta && c.meta.creation_timestamp * 1000;
|
||||
|
||||
const claimStreamUrl = streamUrls ? streamUrls[i] : '';
|
||||
const streamUrl = claimStreamUrl.status === 'fulfilled' ? claimStreamUrl.value : '';
|
||||
|
||||
feed.item({
|
||||
title: title,
|
||||
description: description,
|
||||
|
@ -265,7 +288,7 @@ async function generateFeed(feedLink, channelClaim, claimsInChannel) {
|
|||
guid: undefined, // defaults to 'url'
|
||||
author: undefined, // defaults feed author property
|
||||
date: new Date(date),
|
||||
enclosure: await generateEnclosureForClaimContent(c),
|
||||
enclosure: await generateEnclosureForClaimContent(c, streamUrl),
|
||||
custom_elements: [
|
||||
{ 'itunes:title': title },
|
||||
{ 'itunes:author': channelTitle },
|
||||
|
|
Loading…
Reference in a new issue