2023-03-13 21:07:25 -04:00
|
|
|
import { Streamlink } from '@dragongoose/streamlink';
|
2023-03-07 01:19:05 -05:00
|
|
|
import { Router, Response, Request, NextFunction } from 'express'
|
|
|
|
|
|
|
|
const proxyRouter = Router();
|
|
|
|
|
|
|
|
proxyRouter.get('/img', async (req: Request, res: Response, next: NextFunction) => {
|
|
|
|
const imageUrl = req.query.imageUrl?.toString()
|
|
|
|
if(!imageUrl) return;
|
|
|
|
|
|
|
|
fetch(imageUrl).then((response) => {
|
|
|
|
response.body!.pipeTo(
|
|
|
|
new WritableStream({
|
|
|
|
start() {
|
|
|
|
response.headers.forEach((v, n) => res.setHeader(n, v));
|
|
|
|
},
|
|
|
|
write(chunk) {
|
|
|
|
res.write(chunk);
|
|
|
|
},
|
|
|
|
close() {
|
|
|
|
res.end();
|
|
|
|
},
|
|
|
|
})
|
|
|
|
);
|
|
|
|
})
|
|
|
|
.catch((err) => next(err))
|
|
|
|
})
|
|
|
|
|
2023-03-13 21:07:25 -04:00
|
|
|
proxyRouter.get('/stream/:username/hls.m3u8', (req: Request, res: Response, next: NextFunction) => {
|
|
|
|
console.log(req.params.username)
|
|
|
|
const streamlink = new Streamlink(`https://twitch.tv/${req.params.username}`, {
|
|
|
|
otherArgs: ['--stream-url']
|
|
|
|
})
|
|
|
|
|
|
|
|
streamlink.begin()
|
|
|
|
|
|
|
|
|
|
|
|
streamlink.on('log', async (data) => {
|
|
|
|
// m3u8 url
|
|
|
|
let twitchM3u8url = data.toString()
|
|
|
|
|
|
|
|
const urlRegex =/(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig;
|
|
|
|
const twitchRes = await fetch(twitchM3u8url)
|
|
|
|
let m3u8Data = await twitchRes.text()
|
|
|
|
const matches = m3u8Data.match(urlRegex)
|
|
|
|
if (!matches) return next(new Error('Error proxying HLS'));
|
|
|
|
|
|
|
|
for (let url of matches) {
|
|
|
|
const base64data = Buffer.from(url).toString('base64url')
|
|
|
|
//m3u8Data = m3u8Data.replace(url, `${process.env.URL}/proxy/hls/${base64data}`)
|
|
|
|
}
|
|
|
|
|
|
|
|
res.setHeader('Content-type','application/vnd.apple.mpegurl')
|
|
|
|
res.send(m3u8Data)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
proxyRouter.get('/hls/:encodedUrl' , (req: Request, res: Response, next: NextFunction) => {
|
|
|
|
const unencodedUrl = Buffer.from(req.params.encodedUrl, 'base64url').toString()
|
|
|
|
fetch(unencodedUrl).then((response) => {
|
|
|
|
response.body!.pipeTo(
|
|
|
|
new WritableStream({
|
|
|
|
start() {
|
|
|
|
response.headers.forEach((v, n) => res.setHeader(n, v));
|
|
|
|
},
|
|
|
|
write(chunk) {
|
|
|
|
res.write(chunk);
|
|
|
|
},
|
|
|
|
close() {
|
|
|
|
res.end();
|
|
|
|
},
|
|
|
|
})
|
|
|
|
);
|
|
|
|
})
|
|
|
|
.catch((err) => next(err))
|
|
|
|
})
|
|
|
|
|
2023-03-07 01:19:05 -05:00
|
|
|
export default proxyRouter
|