StreamAsync Javascript mode
Last updated
Last updated
For more examples, head over to
In the streamAsyncJS mode you extract the stream URL asynchronously instead of regular scraping. The function will still be provided with an HTML code.
Functions:
Extracts the search results from the provided HTML.
HTML
JSON
{
"title": "Example Title",
"image": "https://example.com/image.jpg",
"href": "https://grani.me/example"
}
Extracts the details from the provided HTML.
HTML
JSON
{
"description": "An exciting anime series about adventures.",
"aliases": "Alternate Name",
"airdate": "2022"
}
Extracts the episodes from the provided HTML.
HTML
JSON
{
"href": "https://grani.me/episode/123",
"number": "1"
}
Extracts the stream from the provided URL.
HTML
URL
https://example.com/stream/video.mp4
Example:
function searchResults(html) {
const results = [];
const titleRegex = /<h2[^>]*>(.*?)<\/h2>/;
const hrefRegex = /<a\s+href="([^"]+)"\s*[^>]*>/;
const imgRegex = /<img[^>]*src="([^"]+)"[^>]*>/;
const itemRegex = /<div class="my-2 w-64[^"]*"[^>]*>[\s\S]*?<\/div>\s*<\/div>\s*<\/div>/g;
const items = html.match(itemRegex) || [];
items.forEach((itemHtml) => {
const titleMatch = itemHtml.match(titleRegex);
const title = titleMatch ? titleMatch[1].trim() : '';
const hrefMatch = itemHtml.match(hrefRegex);
const href = hrefMatch ? hrefMatch[1].trim() : '';
const imgMatch = itemHtml.match(imgRegex);
const imageUrl = imgMatch ? imgMatch[1].trim() : '';
if (title && href) {
results.push({
title: title,
image: imageUrl,
href: href
});
}
});
return results;
}
function extractDetails(html) {
const details = [];
const descriptionMatch = html.match(/<p class="sm:text-\[1\.05rem\] leading-loose text-justify">([\s\S]*?)<\/p>/);
let description = descriptionMatch ? descriptionMatch[1].trim() : '';
const airdateMatch = html.match(/<td[^>]*title="([^"]+)">[^<]+<\/td>/);
let airdate = airdateMatch ? airdateMatch[1].trim() : '';
if (description && airdate) {
details.push({
description: description,
aliases: 'N/A',
airdate: airdate
});
}
console.log(details);
return details;
}
function extractEpisodes(html) {
const episodes = [];
const htmlRegex = /<a\s+[^>]*href="([^"]*?\/episode\/[^"]*?)"[^>]*>[\s\S]*?الحلقة\s+(\d+)[\s\S]*?<\/a>/gi;
const plainTextRegex = /الحلقة\s+(\d+)/g;
let matches;
if ((matches = html.match(htmlRegex))) {
matches.forEach(link => {
const hrefMatch = link.match(/href="([^"]+)"/);
const numberMatch = link.match(/الحلقة\s+(\d+)/);
if (hrefMatch && numberMatch) {
const href = hrefMatch[1];
const number = numberMatch[1];
episodes.push({
href: href,
number: number
});
}
});
} else if ((matches = html.match(plainTextRegex))) {
matches.forEach(match => {
const numberMatch = match.match(/\d+/);
if (numberMatch) {
episodes.push({
href: null,
number: numberMatch[0]
});
}
});
}
console.log(episodes);
return episodes;
}
async function extractStreamUrl(html) {
try {
const sourceMatch = html.match(/data-source="([^"]+)"/);
const embedUrl = sourceMatch?.[1]?.replace(/&/g, '&');
if (!embedUrl) return null;
const response = await fetch(embedUrl);
const data = await response;
const videoUrl = data.match(/src:\s*'(https:\/\/[^']+\.mp4[^']*)'/)?.[1];
console.log(videoUrl);
return videoUrl || null;
} catch (error) {
return null;
}
}