refactoring & fixes
- added duration check to vimeo module - fixed quality picking in vimeo module for progressive video type - dropping requests from ie users instead of redirecting - probably something else but i forgot to be honest
This commit is contained in:
@@ -43,16 +43,14 @@ export function createStream(obj) {
|
||||
export function verifyStream(ip, id, hmac, exp) {
|
||||
try {
|
||||
let streamInfo = streamCache.get(id);
|
||||
if (streamInfo) {
|
||||
let ghmac = sha256(`${id},${streamInfo.service},${ip},${exp}`, salt);
|
||||
if (hmac == ghmac && exp.toString() == streamInfo.exp && ghmac == streamInfo.hmac && ip == streamInfo.ip && exp > Math.floor(new Date().getTime())) {
|
||||
return streamInfo;
|
||||
} else {
|
||||
return { error: 'Unauthorized', status: 401 };
|
||||
}
|
||||
} else {
|
||||
if (!streamInfo) {
|
||||
return { error: 'this stream token does not exist', status: 400 };
|
||||
}
|
||||
let ghmac = sha256(`${id},${streamInfo.service},${ip},${exp}`, salt);
|
||||
if (hmac == ghmac && exp.toString() == streamInfo.exp && ghmac == streamInfo.hmac && ip == streamInfo.ip && exp > Math.floor(new Date().getTime())) {
|
||||
return streamInfo;
|
||||
}
|
||||
return { error: 'Unauthorized', status: 401 };
|
||||
} catch (e) {
|
||||
return { status: 500, body: { status: "error", text: "Internal Server Error" } };
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { services, quality as mq } from "../config.js";
|
||||
|
||||
// TO-DO: remake entirety of this module to be more of how quality picking is done in vimeo module
|
||||
function closest(goal, array) {
|
||||
return array.sort().reduce(function (prev, curr) {
|
||||
return (Math.abs(curr - goal) < Math.abs(prev - goal) ? curr : prev);
|
||||
@@ -15,9 +16,7 @@ export default function(service, quality, maxQuality) {
|
||||
if (quality >= maxQuality || quality == maxQuality) return maxQuality;
|
||||
|
||||
if (quality < maxQuality) {
|
||||
if (services[service]["quality"][quality]) {
|
||||
return quality
|
||||
} else {
|
||||
if (!services[service]["quality"][quality]) {
|
||||
let s = Object.keys(services[service]["quality_match"]).filter((q) => {
|
||||
if (q <= quality) {
|
||||
return true
|
||||
@@ -25,5 +24,6 @@ export default function(service, quality, maxQuality) {
|
||||
})
|
||||
return closest(quality, s)
|
||||
}
|
||||
return quality
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,24 +5,24 @@ import { streamAudioOnly, streamDefault, streamLiveRender, streamVideoOnly } fro
|
||||
export default function(res, ip, id, hmac, exp) {
|
||||
try {
|
||||
let streamInfo = verifyStream(ip, id, hmac, exp);
|
||||
if (!streamInfo.error) {
|
||||
if (streamInfo.isAudioOnly && streamInfo.type !== "bridge") {
|
||||
streamAudioOnly(streamInfo, res);
|
||||
} else {
|
||||
switch (streamInfo.type) {
|
||||
case "render":
|
||||
streamLiveRender(streamInfo, res);
|
||||
break;
|
||||
case "mute":
|
||||
streamVideoOnly(streamInfo, res);
|
||||
break;
|
||||
default:
|
||||
streamDefault(streamInfo, res);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (streamInfo.error) {
|
||||
res.status(streamInfo.status).json(apiJSON(0, { t: streamInfo.error }).body);
|
||||
return;
|
||||
}
|
||||
if (streamInfo.isAudioOnly && streamInfo.type !== "bridge") {
|
||||
streamAudioOnly(streamInfo, res);
|
||||
return;
|
||||
}
|
||||
switch (streamInfo.type) {
|
||||
case "render":
|
||||
streamLiveRender(streamInfo, res);
|
||||
break;
|
||||
case "mute":
|
||||
streamVideoOnly(streamInfo, res);
|
||||
break;
|
||||
default:
|
||||
streamDefault(streamInfo, res);
|
||||
break;
|
||||
}
|
||||
} catch (e) {
|
||||
res.status(500).json({ status: "error", text: "Internal Server Error" });
|
||||
|
||||
@@ -27,39 +27,41 @@ export function streamDefault(streamInfo, res) {
|
||||
}
|
||||
export function streamLiveRender(streamInfo, res) {
|
||||
try {
|
||||
if (streamInfo.urls.length === 2) {
|
||||
let format = streamInfo.filename.split('.')[streamInfo.filename.split('.').length - 1], args = [
|
||||
'-loglevel', '-8',
|
||||
'-i', streamInfo.urls[0],
|
||||
'-i', streamInfo.urls[1],
|
||||
'-map', '0:v',
|
||||
'-map', '1:a',
|
||||
];
|
||||
args = args.concat(ffmpegArgs[format])
|
||||
if (streamInfo.time) args.push('-t', msToTime(streamInfo.time));
|
||||
args.push('-f', format, 'pipe:3');
|
||||
const ffmpegProcess = spawn(ffmpeg, args, {
|
||||
windowsHide: true,
|
||||
stdio: [
|
||||
'inherit', 'inherit', 'inherit',
|
||||
'pipe'
|
||||
],
|
||||
});
|
||||
res.setHeader('Connection', 'keep-alive');
|
||||
res.setHeader('Content-Disposition', `attachment; filename="${streamInfo.filename}"`);
|
||||
ffmpegProcess.stdio[3].pipe(res);
|
||||
ffmpegProcess.on('disconnect', () => ffmpegProcess.kill());
|
||||
ffmpegProcess.on('close', () => ffmpegProcess.kill());
|
||||
ffmpegProcess.on('exit', () => ffmpegProcess.kill());
|
||||
res.on('finish', () => ffmpegProcess.kill());
|
||||
res.on('close', () => ffmpegProcess.kill());
|
||||
ffmpegProcess.on('error', (err) => {
|
||||
ffmpegProcess.kill();
|
||||
res.end();
|
||||
});
|
||||
} else {
|
||||
if (!streamInfo.urls.length === 2) {
|
||||
res.end();
|
||||
return;
|
||||
}
|
||||
let format = streamInfo.filename.split('.')[streamInfo.filename.split('.').length - 1], args = [
|
||||
'-loglevel', '-8',
|
||||
'-i', streamInfo.urls[0],
|
||||
'-i', streamInfo.urls[1],
|
||||
'-map', '0:v',
|
||||
'-map', '1:a',
|
||||
];
|
||||
args = args.concat(ffmpegArgs[format])
|
||||
if (streamInfo.time) args.push('-t', msToTime(streamInfo.time));
|
||||
args.push('-f', format, 'pipe:3');
|
||||
const ffmpegProcess = spawn(ffmpeg, args, {
|
||||
windowsHide: true,
|
||||
stdio: [
|
||||
'inherit', 'inherit', 'inherit',
|
||||
'pipe'
|
||||
],
|
||||
});
|
||||
res.setHeader('Connection', 'keep-alive');
|
||||
res.setHeader('Content-Disposition', `attachment; filename="${streamInfo.filename}"`);
|
||||
ffmpegProcess.stdio[3].pipe(res);
|
||||
|
||||
ffmpegProcess.on('disconnect', () => ffmpegProcess.kill());
|
||||
ffmpegProcess.on('close', () => ffmpegProcess.kill());
|
||||
ffmpegProcess.on('exit', () => ffmpegProcess.kill());
|
||||
res.on('finish', () => ffmpegProcess.kill());
|
||||
res.on('close', () => ffmpegProcess.kill());
|
||||
ffmpegProcess.on('error', (err) => {
|
||||
ffmpegProcess.kill();
|
||||
res.end();
|
||||
});
|
||||
|
||||
} catch (e) {
|
||||
res.end();
|
||||
}
|
||||
@@ -93,6 +95,7 @@ export function streamAudioOnly(streamInfo, res) {
|
||||
res.setHeader('Connection', 'keep-alive');
|
||||
res.setHeader('Content-Disposition', `attachment; filename="${streamInfo.filename}.${streamInfo.audioFormat}"`);
|
||||
ffmpegProcess.stdio[3].pipe(res);
|
||||
|
||||
ffmpegProcess.on('disconnect', () => ffmpegProcess.kill());
|
||||
ffmpegProcess.on('close', () => ffmpegProcess.kill());
|
||||
ffmpegProcess.on('exit', () => ffmpegProcess.kill());
|
||||
@@ -125,6 +128,7 @@ export function streamVideoOnly(streamInfo, res) {
|
||||
res.setHeader('Connection', 'keep-alive');
|
||||
res.setHeader('Content-Disposition', `attachment; filename="${streamInfo.filename.split('.')[0]}_mute.${format}"`);
|
||||
ffmpegProcess.stdio[3].pipe(res);
|
||||
|
||||
ffmpegProcess.on('disconnect', () => ffmpegProcess.kill());
|
||||
ffmpegProcess.on('close', () => ffmpegProcess.kill());
|
||||
ffmpegProcess.on('exit', () => ffmpegProcess.kill());
|
||||
|
||||
Reference in New Issue
Block a user