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');
|
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;
|
const value = claim.value;
|
||||||
if (!value || !value.stream_type) {
|
if (!value || !value.stream_type) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
const fileExt = value.source && value.source.media_type && '.' + Mime.extension(value.source.media_type);
|
const fileExt = value.source && value.source.media_type && '.' + Mime.extension(value.source.media_type);
|
||||||
|
|
||||||
switch (value.stream_type) {
|
switch (value.stream_type) {
|
||||||
case 'video':
|
case 'video':
|
||||||
return {
|
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',
|
type: (value.source && value.source.media_type) || 'video/mp4',
|
||||||
size: (value.source && value.source.size) || 0, // Per spec, 0 is a valid fallback.
|
size: (value.source && value.source.size) || 0, // Per spec, 0 is a valid fallback.
|
||||||
};
|
};
|
||||||
|
|
||||||
case 'audio':
|
case 'audio':
|
||||||
return {
|
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',
|
type: (value.source && value.source.media_type) || 'audio/mpeg',
|
||||||
size: (value.source && value.source.size) || 0, // Per spec, 0 is a valid fallback.
|
size: (value.source && value.source.size) || 0, // Per spec, 0 is a valid fallback.
|
||||||
};
|
};
|
||||||
case 'image':
|
case 'image':
|
||||||
return {
|
return {
|
||||||
url: (await fetchStreamUrl(claim.name, claim.claim_id)) + (fileExt || '.jpeg'),
|
url: streamUrl + (fileExt || '.jpeg'),
|
||||||
type: (value.source && value.source.media_type) || 'image/jpeg',
|
type: (value.source && value.source.media_type) || 'image/jpeg',
|
||||||
size: (value.source && value.source.size) || 0, // Per spec, 0 is a valid fallback.
|
size: (value.source && value.source.size) || 0, // Per spec, 0 is a valid fallback.
|
||||||
};
|
};
|
||||||
case 'document':
|
case 'document':
|
||||||
case 'software':
|
case 'software':
|
||||||
return {
|
return {
|
||||||
url: await fetchStreamUrl(claim.name, claim.claim_id),
|
url: streamUrl,
|
||||||
type: (value.source && value.source.media_type) || undefined,
|
type: (value.source && value.source.media_type) || undefined,
|
||||||
size: (value.source && value.source.size) || 0, // Per spec, 0 is a valid fallback.
|
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
|
// "Note: Although you can specify more than one category and subcategory
|
||||||
// in your RSS feed, Apple Podcasts only recognizes the first category and
|
// in your RSS feed, Apple Podcasts only recognizes the first category and
|
||||||
// subcategory."
|
// subcategory."
|
||||||
// --> The only parse the first found tag.
|
// --> They only parse the first found tag.
|
||||||
return itunesCategory.replace('&', '&');
|
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 ---
|
// --- Content ---
|
||||||
for (let i = 0; i < claimsInChannel.length; ++i) {
|
for (let i = 0; i < claimsInChannel.length; ++i) {
|
||||||
const c = claimsInChannel[i];
|
const c = claimsInChannel[i];
|
||||||
|
@ -258,6 +278,9 @@ async function generateFeed(feedLink, channelClaim, claimsInChannel) {
|
||||||
const date =
|
const date =
|
||||||
c.value && c.value.release_time ? c.value.release_time * 1000 : c.meta && c.meta.creation_timestamp * 1000;
|
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({
|
feed.item({
|
||||||
title: title,
|
title: title,
|
||||||
description: description,
|
description: description,
|
||||||
|
@ -265,7 +288,7 @@ async function generateFeed(feedLink, channelClaim, claimsInChannel) {
|
||||||
guid: undefined, // defaults to 'url'
|
guid: undefined, // defaults to 'url'
|
||||||
author: undefined, // defaults feed author property
|
author: undefined, // defaults feed author property
|
||||||
date: new Date(date),
|
date: new Date(date),
|
||||||
enclosure: await generateEnclosureForClaimContent(c),
|
enclosure: await generateEnclosureForClaimContent(c, streamUrl),
|
||||||
custom_elements: [
|
custom_elements: [
|
||||||
{ 'itunes:title': title },
|
{ 'itunes:title': title },
|
||||||
{ 'itunes:author': channelTitle },
|
{ 'itunes:author': channelTitle },
|
||||||
|
|
Loading…
Reference in a new issue