Release v0.4: Add PornHub support / Server-side streaming / Plyr.js / Video srcset #96
|
@ -19,6 +19,27 @@ export const findGetMediaUrlInTagblock = (
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const findGetRelatedUrlInTagblock = (
|
||||||
|
tagBlock: string): string | null => {
|
||||||
|
|
||||||
|
const getMediaIndex = tagBlock.indexOf('player_related_datas');
|
||||||
|
|
||||||
|
if (getMediaIndex === -1) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
const start = tagBlock.lastIndexOf('"', getMediaIndex);
|
||||||
|
const end = tagBlock.indexOf('"', getMediaIndex);
|
||||||
|
|
||||||
|
const substr = tagBlock.substring(start, end);
|
||||||
|
|
||||||
|
if (substr.length > 0) {
|
||||||
|
return substr.replace(/\\/g, '').replace(/"/g, '');
|
||||||
|
}
|
||||||
|
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
export const createSessionCookie = (responseSetCookies: string[]): string => {
|
export const createSessionCookie = (responseSetCookies: string[]): string => {
|
||||||
let pieces: string[] = []
|
let pieces: string[] = []
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { PORNHUB_BASE_URL } from "@/constants/urls"
|
import { PORNHUB_BASE_URL } from "@/constants/urls"
|
||||||
import axios, { AxiosHeaders } from "axios"
|
import axios, { AxiosHeaders } from "axios"
|
||||||
import { getHeadersWithCookie } from "../common/headers"
|
import { getHeadersWithCookie } from "../common/headers"
|
||||||
import { VideoSourceItem } from "@/meta/data"
|
import { GalleryData, VideoSourceItem } from "@/meta/data"
|
||||||
import { Platforms } from "@/meta/settings"
|
import { Platforms } from "@/meta/settings"
|
||||||
|
|
||||||
interface PornHubVideoSrcElem {
|
interface PornHubVideoSrcElem {
|
||||||
|
@ -45,3 +45,66 @@ export const getPornHubMediaUrlList = async (url: string, sessionCookie: string)
|
||||||
|
|
||||||
return videos
|
return videos
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function containsAtLeastThreeSpaces(input: string): boolean {
|
||||||
|
// Conta il numero di spazi nella stringa
|
||||||
|
const spaceCount = (input.match(/ /g) || []).length;
|
||||||
|
// Verifica se ci sono almeno tre spazi
|
||||||
|
return spaceCount >= 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getPornHubRelatedVideoData = async (url: string, sessionCookie: string): Promise<GalleryData[]> => {
|
||||||
|
|
||||||
|
const headersWithCookie = getHeadersWithCookie(PORNHUB_BASE_URL, sessionCookie)
|
||||||
|
|
||||||
|
let gallery: GalleryData[] = []
|
||||||
|
|
||||||
|
await axios.get(url, headersWithCookie)
|
||||||
|
.then(async response => {
|
||||||
|
|
||||||
|
if (response.data?.related) {
|
||||||
|
|
||||||
|
Array(response.data.related).map((related: any[], key) => {
|
||||||
|
|
||||||
|
related.map((rel: string[], key) => {
|
||||||
|
|
||||||
|
let galleryElem: GalleryData = {
|
||||||
|
videoUrl: '',
|
||||||
|
imgUrl: '',
|
||||||
|
text: '',
|
||||||
|
platform: Platforms.pornhub
|
||||||
|
}
|
||||||
|
|
||||||
|
rel.map((str, key) => {
|
||||||
|
|
||||||
|
if (String(str).includes('.jpg')) {
|
||||||
|
galleryElem.imgUrl = str;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (String(str).includes('viewkey')) {
|
||||||
|
galleryElem.videoUrl = str.split('=')[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (containsAtLeastThreeSpaces(String(str))) {
|
||||||
|
galleryElem.text = str;
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
gallery.push(galleryElem)
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
return gallery;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
.catch(error => console.log(error))
|
||||||
|
|
||||||
|
return gallery
|
||||||
|
}
|
|
@ -1,14 +1,14 @@
|
||||||
import { PORNHUB_BASE_URL, PORNHUB_BASE_URL_VIDEO } from "@/constants/urls";
|
import { PORNHUB_BASE_URL, PORNHUB_BASE_URL_VIDEO } from "@/constants/urls";
|
||||||
import { FetchParams, GalleryData, VideoData, VideoSourceItem } from "@/meta/data";
|
import { FetchParams, GalleryData, VideoData, VideoSourceItem } from "@/meta/data";
|
||||||
import { getHeaders, getHeadersWithCookie } from "../common/headers";
|
import { getHeaders } from "../common/headers";
|
||||||
import { getDataFromRedis, storeDataIntoRedis } from "@/redis/client";
|
import { getDataFromRedis, storeDataIntoRedis } from "@/redis/client";
|
||||||
import { DEFAULT_PORNHUB_VIDEO_EXPIRY, DEFAULT_RELATED_VIDEO_KEY_PATH } from "@/constants/redis";
|
import { DEFAULT_PORNHUB_GALLERY_EXPIRY, DEFAULT_PORNHUB_VIDEO_EXPIRY, DEFAULT_RELATED_VIDEO_KEY_PATH } from "@/constants/redis";
|
||||||
|
|
||||||
import * as cheerio from "cheerio";
|
import * as cheerio from "cheerio";
|
||||||
|
|
||||||
import axios, { AxiosError } from "axios";
|
import axios, { AxiosError } from "axios";
|
||||||
import { createSessionCookie, findGetMediaUrlInTagblock } from "../common/mindgeek";
|
import { createSessionCookie, findGetMediaUrlInTagblock, findGetRelatedUrlInTagblock } from "../common/mindgeek";
|
||||||
import { getPornHubMediaUrlList } from "./url";
|
import { getPornHubMediaUrlList, getPornHubRelatedVideoData } from "./url";
|
||||||
|
|
||||||
export const fetchPornHubVideoData = async (videoId: string, params?: FetchParams): Promise<[VideoData, GalleryData[]]> => {
|
export const fetchPornHubVideoData = async (videoId: string, params?: FetchParams): Promise<[VideoData, GalleryData[]]> => {
|
||||||
|
|
||||||
|
@ -17,16 +17,19 @@ export const fetchPornHubVideoData = async (videoId: string, params?: FetchParam
|
||||||
srcSet: []
|
srcSet: []
|
||||||
}
|
}
|
||||||
|
|
||||||
let mediaUrl, sessionCookie, convertedData: VideoSourceItem[]
|
let relatedData: GalleryData[] = [];
|
||||||
|
|
||||||
|
let mediaUrl, relatedUrl, sessionCookie, convertedData: VideoSourceItem[]
|
||||||
|
|
||||||
let reqHeaders = getHeaders(PORNHUB_BASE_URL)
|
let reqHeaders = getHeaders(PORNHUB_BASE_URL)
|
||||||
|
|
||||||
const queryUrl = `${PORNHUB_BASE_URL_VIDEO}${videoId.replace(/\//g, '')}`
|
const queryUrl = `${PORNHUB_BASE_URL_VIDEO}${videoId.replace(/\//g, '')}`
|
||||||
|
|
||||||
const cachedVideoData = await getDataFromRedis(queryUrl)
|
const cachedVideoData = await getDataFromRedis(queryUrl)
|
||||||
|
const cachedRelatedData = await getDataFromRedis(queryUrl + DEFAULT_RELATED_VIDEO_KEY_PATH)
|
||||||
|
|
||||||
if (cachedVideoData) {
|
if (cachedVideoData) {
|
||||||
return [cachedVideoData as VideoData, []]
|
return [cachedVideoData as VideoData, cachedRelatedData as GalleryData[] ?? []]
|
||||||
}
|
}
|
||||||
|
|
||||||
await axios.get(queryUrl, reqHeaders)
|
await axios.get(queryUrl, reqHeaders)
|
||||||
|
@ -50,6 +53,15 @@ export const fetchPornHubVideoData = async (videoId: string, params?: FetchParam
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
scriptTags.map((idx, elem) => {
|
||||||
|
const getRelatedUrl = findGetRelatedUrlInTagblock($(elem).toString()) ?? null
|
||||||
|
|
||||||
|
if (getRelatedUrl) {
|
||||||
|
relatedUrl = getRelatedUrl
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
}).catch((error: AxiosError) => {
|
}).catch((error: AxiosError) => {
|
||||||
// error handling goes here
|
// error handling goes here
|
||||||
});
|
});
|
||||||
|
@ -61,5 +73,16 @@ export const fetchPornHubVideoData = async (videoId: string, params?: FetchParam
|
||||||
await storeDataIntoRedis(queryUrl, data, DEFAULT_PORNHUB_VIDEO_EXPIRY);
|
await storeDataIntoRedis(queryUrl, data, DEFAULT_PORNHUB_VIDEO_EXPIRY);
|
||||||
}
|
}
|
||||||
|
|
||||||
return [ data, []]
|
if (sessionCookie && relatedUrl) {
|
||||||
|
if (cachedRelatedData) {
|
||||||
|
relatedData = cachedRelatedData as GalleryData[]
|
||||||
|
} else {
|
||||||
|
relatedData = await getPornHubRelatedVideoData(relatedUrl, sessionCookie)
|
||||||
|
|
||||||
|
await storeDataIntoRedis(queryUrl + DEFAULT_RELATED_VIDEO_KEY_PATH, relatedData, DEFAULT_PORNHUB_GALLERY_EXPIRY);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return [ data, relatedData ]
|
||||||
}
|
}
|
Loading…
Reference in New Issue