Spaces:
Running
Running
import HLSParser from "hls-parser"; | |
import { env } from "../../config.js"; | |
let _token; | |
function getExp(token) { | |
return JSON.parse( | |
Buffer.from(token.split('.')[1], 'base64') | |
).exp * 1000; | |
} | |
const getToken = async () => { | |
if (_token && getExp(_token) > new Date().getTime()) { | |
return _token; | |
} | |
const req = await fetch('https://graphql.api.dailymotion.com/oauth/token', { | |
method: 'POST', | |
headers: { | |
'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8', | |
'User-Agent': 'dailymotion/240213162706 CFNetwork/1492.0.1 Darwin/23.3.0', | |
'Authorization': 'Basic MGQyZDgyNjQwOWFmOWU3MmRiNWQ6ODcxNmJmYTVjYmEwMmUwMGJkYTVmYTg1NTliNDIwMzQ3NzIyYWMzYQ==' | |
}, | |
body: 'traffic_segment=&grant_type=client_credentials' | |
}).then(r => r.json()).catch(() => {}); | |
if (req.access_token) { | |
return _token = req.access_token; | |
} | |
} | |
export default async function({ id }) { | |
const token = await getToken(); | |
if (!token) return { error: "fetch.fail" }; | |
const req = await fetch('https://graphql.api.dailymotion.com/', | |
{ | |
method: 'POST', | |
headers: { | |
'User-Agent': 'dailymotion/240213162706 CFNetwork/1492.0.1 Darwin/23.3.0', | |
Authorization: `Bearer ${token}`, | |
'Content-Type': 'application/json', | |
'X-DM-AppInfo-Version': '7.16.0_240213162706', | |
'X-DM-AppInfo-Type': 'iosapp', | |
'X-DM-AppInfo-Id': 'com.dailymotion.dailymotion' | |
}, | |
body: JSON.stringify({ | |
operationName: "Media", | |
query: ` | |
query Media($xid: String!, $password: String) { | |
media(xid: $xid, password: $password) { | |
__typename | |
... on Video { | |
xid | |
hlsURL | |
duration | |
title | |
channel { | |
displayName | |
} | |
} | |
} | |
} | |
`, | |
variables: { xid: id } | |
}) | |
} | |
).then(r => r.status === 200 && r.json()).catch(() => {}); | |
const media = req?.data?.media; | |
if (media?.__typename !== 'Video' || !media.hlsURL) { | |
return { error: "fetch.empty" } | |
} | |
if (media.duration > env.durationLimit) { | |
return { error: "content.too_long" }; | |
} | |
const manifest = await fetch(media.hlsURL).then(r => r.text()).catch(() => {}); | |
if (!manifest) return { error: "fetch.fail" }; | |
const bestQuality = HLSParser.parse(manifest).variants | |
.filter(v => v.codecs.includes('avc1')) | |
.reduce((a, b) => a.bandwidth > b.bandwidth ? a : b); | |
if (!bestQuality) return { error: "fetch.empty" } | |
const fileMetadata = { | |
title: media.title, | |
artist: media.channel.displayName | |
} | |
return { | |
urls: bestQuality.uri, | |
isM3U8: true, | |
filenameAttributes: { | |
service: 'dailymotion', | |
id: media.xid, | |
title: fileMetadata.title, | |
author: fileMetadata.artist, | |
resolution: `${bestQuality.resolution.width}x${bestQuality.resolution.height}`, | |
qualityLabel: `${bestQuality.resolution.height}p`, | |
extension: 'mp4' | |
}, | |
fileMetadata | |
} | |
} |