mirror of
https://git.luna-app.eu/50n50/sources
synced 2025-12-22 21:56:23 +01:00
Add audible/audible.js
This commit is contained in:
parent
8ce8de0b13
commit
fb22fb6237
1 changed files with 215 additions and 0 deletions
215
audible/audible.js
Normal file
215
audible/audible.js
Normal file
|
|
@ -0,0 +1,215 @@
|
|||
async function searchResults(keyword) {
|
||||
const results = [];
|
||||
let pageNumber = 1;
|
||||
let hasMore = true;
|
||||
|
||||
try {
|
||||
while (hasMore) {
|
||||
const headers = {
|
||||
"next-action": await extractNextActionIdentifier(),
|
||||
"Content-Type": "text/plain"
|
||||
};
|
||||
console.log(JSON.stringify(headers));
|
||||
const postData = `[${pageNumber},"${keyword}",""]`;
|
||||
const response = await fetchv2("https://mapple.site/audiobooks?search=" + encodeURIComponent(keyword), headers, "POST", postData);
|
||||
const text = await response.text();
|
||||
console.log("Page " + pageNumber + " response:", text);
|
||||
|
||||
const lines = text.split('\n').filter(line => line.trim());
|
||||
let foundBooks = false;
|
||||
|
||||
for (const line of lines) {
|
||||
try {
|
||||
const data = JSON.parse(line.substring(line.indexOf('{')));
|
||||
|
||||
if (data.books && Array.isArray(data.books)) {
|
||||
foundBooks = true;
|
||||
for (const book of data.books) {
|
||||
results.push({
|
||||
title: book.title || "Untitled",
|
||||
image: book.image || "",
|
||||
href: "https://mapple.site/listen/" + (book.$id || "") + "/" + encodeURIComponent(book.title || "untitled")
|
||||
});
|
||||
}
|
||||
hasMore = data.hasMore === true;
|
||||
console.log("hasMore: " + hasMore);
|
||||
}
|
||||
} catch (e) {
|
||||
}
|
||||
}
|
||||
|
||||
if (!foundBooks) {
|
||||
hasMore = false;
|
||||
}
|
||||
|
||||
pageNumber++;
|
||||
}
|
||||
|
||||
return JSON.stringify(results);
|
||||
} catch (err) {
|
||||
console.log("Search error:", err);
|
||||
return JSON.stringify([{
|
||||
title: "Error",
|
||||
image: "Error",
|
||||
href: "Error"
|
||||
}]);
|
||||
}
|
||||
}
|
||||
|
||||
async function extractDetails(url) {
|
||||
try {
|
||||
return JSON.stringify([{
|
||||
description: "",
|
||||
aliases: "",
|
||||
airdate: ""
|
||||
}]);
|
||||
} catch (err) {
|
||||
return JSON.stringify([{
|
||||
description: "Error",
|
||||
aliases: "Error",
|
||||
airdate: "Error"
|
||||
}]);
|
||||
}
|
||||
}
|
||||
|
||||
async function extractEpisodes(url) {
|
||||
const results = [];
|
||||
try {
|
||||
const fetchResponse = await fetchv2(url, {
|
||||
"rsc": "1"
|
||||
});
|
||||
const fetchText = await fetchResponse.text();
|
||||
|
||||
const audioItemsMatch = fetchText.match(/"audio_items":\[([^\]]+)\]/);
|
||||
|
||||
if (audioItemsMatch && audioItemsMatch[1]) {
|
||||
const audioItemsStr = audioItemsMatch[1];
|
||||
const urlMatches = audioItemsStr.match(/"(https?:\/\/[^"]+)"/g);
|
||||
|
||||
if (urlMatches) {
|
||||
for (let i = 0; i < urlMatches.length; i++) {
|
||||
const audioUrl = urlMatches[i].replace(/"/g, '');
|
||||
results.push({
|
||||
href: audioUrl,
|
||||
number: i + 1,
|
||||
title: `Chapter ${i + 1}`
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return JSON.stringify(results);
|
||||
} catch (err) {
|
||||
console.log("Episodes error:", err);
|
||||
return JSON.stringify([{
|
||||
href: "Error",
|
||||
number: "Error",
|
||||
title: "Error"
|
||||
}]);
|
||||
}
|
||||
}
|
||||
|
||||
async function extractStreamUrl(url) {
|
||||
try {
|
||||
const headers = {
|
||||
"Host": "ipaudio.club",
|
||||
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:146.0) Gecko/20100101 Firefox/146.0",
|
||||
"Accept": "*/*",
|
||||
"Accept-Language": "en-US,en;q=0.5",
|
||||
"Accept-Encoding": "gzip, deflate, br, zstd",
|
||||
"Connection": "keep-alive",
|
||||
"Sec-Fetch-Dest": "empty",
|
||||
"Sec-Fetch-Mode": "no-cors",
|
||||
"Sec-Fetch-Site": "cross-site",
|
||||
"Priority": "u=4",
|
||||
"Pragma": "no-cache",
|
||||
"Cache-Control": "no-cache"
|
||||
};
|
||||
|
||||
const streams = [{
|
||||
title: `Audio Stream 1`,
|
||||
streamUrl: url,
|
||||
headers: headers
|
||||
}];
|
||||
|
||||
return JSON.stringify({
|
||||
streams: streams,
|
||||
subtitle: ""
|
||||
});
|
||||
|
||||
} catch (err) {
|
||||
console.log("Stream error:", err);
|
||||
return JSON.stringify({
|
||||
streams: [{
|
||||
title: "Error",
|
||||
streamUrl: "",
|
||||
headers: {}
|
||||
}],
|
||||
subtitle: ""
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async function soraFetch(url, options = { headers: {}, method: 'GET', body: null, encoding: 'utf-8' }) {
|
||||
try {
|
||||
return await fetchv2(
|
||||
url,
|
||||
options.headers ?? {},
|
||||
options.method ?? 'GET',
|
||||
options.body ?? null,
|
||||
true,
|
||||
options.encoding ?? 'utf-8'
|
||||
);
|
||||
} catch(e) {
|
||||
try {
|
||||
return await fetch(url, options);
|
||||
} catch(error) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function extractNextActionIdentifier() {
|
||||
const htmlResponse = await soraFetch(atob("aHR0cHM6Ly9tYXBwbGUuc2l0ZS9hdWRpb2Jvb2tz"));
|
||||
const htmlText = await htmlResponse.text();
|
||||
|
||||
const pageMatch = htmlText.match(/<script[^>]*src="([^"]*app\/audiobooks\/page-[^"]*\.js)"[^>]*><\/script>/);
|
||||
|
||||
if (!pageMatch || !pageMatch[1]) {
|
||||
throw new Error("error 1");
|
||||
}
|
||||
|
||||
const beforePageMatch = htmlText.match(/<script[^>]*src="([^"]*\.js)"[^>]*><\/script><script[^>]*src="[^"]*app\/audiobooks\/page-[^"]*\.js"/);
|
||||
|
||||
if (!beforePageMatch || !beforePageMatch[1]) {
|
||||
throw new Error("error 2");
|
||||
}
|
||||
|
||||
let targetUrl = beforePageMatch[1];
|
||||
if (targetUrl.startsWith('/_next/')) {
|
||||
targetUrl = 'https://mapple.site' + targetUrl;
|
||||
} else if (!targetUrl.startsWith('http')) {
|
||||
targetUrl = 'https://mapple.site/' + targetUrl;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await soraFetch(targetUrl);
|
||||
const text = await response.text();
|
||||
|
||||
let actionMatch = text.match(/createServerReference\)\("([a-f0-9]{40,})"[^"]*"getStreamUrl/);
|
||||
if (!actionMatch) {
|
||||
actionMatch = text.match(/createServerReference\)\("([a-f0-9]{40,})"/);
|
||||
}
|
||||
if (!actionMatch) {
|
||||
actionMatch = text.match(/"([a-f0-9]{40,})"[^"]*"getStreamUrl/);
|
||||
}
|
||||
|
||||
if (actionMatch && actionMatch[1]) {
|
||||
return actionMatch[1];
|
||||
}
|
||||
} catch (e) {
|
||||
throw new Error("error 3: " + e);
|
||||
}
|
||||
|
||||
throw new Error("error 4");
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue