89 lines
2.3 KiB
JavaScript
89 lines
2.3 KiB
JavaScript
const http = require('http');
|
|
const https = require('https');
|
|
|
|
const requestJson = (url, { timeoutMs = 2000 } = {}) => {
|
|
return new Promise((resolve, reject) => {
|
|
const u = new URL(url);
|
|
const lib = u.protocol === 'https:' ? https : http;
|
|
|
|
const req = lib.request(
|
|
{
|
|
protocol: u.protocol,
|
|
hostname: u.hostname,
|
|
port: u.port,
|
|
path: `${u.pathname}${u.search}`,
|
|
method: 'GET'
|
|
},
|
|
(res) => {
|
|
let raw = '';
|
|
res.setEncoding('utf8');
|
|
res.on('data', (chunk) => (raw += chunk));
|
|
res.on('end', () => {
|
|
if (res.statusCode && (res.statusCode < 200 || res.statusCode >= 300)) {
|
|
return reject(new Error(`SRS HTTP API status ${res.statusCode}`));
|
|
}
|
|
|
|
try {
|
|
resolve(JSON.parse(raw || '{}'));
|
|
} catch (e) {
|
|
reject(new Error('Invalid JSON from SRS HTTP API'));
|
|
}
|
|
});
|
|
}
|
|
);
|
|
|
|
req.on('error', reject);
|
|
req.setTimeout(timeoutMs, () => {
|
|
req.destroy(new Error('SRS HTTP API request timeout'));
|
|
});
|
|
req.end();
|
|
});
|
|
};
|
|
|
|
const normalizeStreamName = (s) => {
|
|
if (!s) return null;
|
|
if (typeof s === 'string') return s;
|
|
return s.stream || s.name || s.id || null;
|
|
};
|
|
|
|
const isPublishActive = (streamObj) => {
|
|
const publish = streamObj && streamObj.publish;
|
|
if (!publish) return false;
|
|
if (typeof publish.active === 'boolean') return publish.active;
|
|
return Boolean(publish.cid);
|
|
};
|
|
|
|
let warnedOnce = false;
|
|
|
|
const getActiveStreamKeys = async ({ app = 'live' } = {}) => {
|
|
const host = process.env.SRS_HOST || 'localhost';
|
|
const apiPort = process.env.SRS_API_PORT || 1985;
|
|
|
|
const url = `http://${host}:${apiPort}/api/v1/streams?count=100`;
|
|
|
|
try {
|
|
const payload = await requestJson(url, { timeoutMs: 1500 });
|
|
const streams = payload.streams || payload.data?.streams || [];
|
|
|
|
const active = new Set();
|
|
for (const s of streams) {
|
|
if (app && s.app && s.app !== app) continue;
|
|
if (!isPublishActive(s)) continue;
|
|
const name = normalizeStreamName(s);
|
|
if (name) active.add(name);
|
|
}
|
|
|
|
return active;
|
|
} catch (e) {
|
|
if (!warnedOnce) {
|
|
warnedOnce = true;
|
|
console.warn(`[SRS] HTTP API unavailable at ${url}. Will fallback to callbacks/in-memory status.`);
|
|
}
|
|
return new Set();
|
|
}
|
|
};
|
|
|
|
module.exports = {
|
|
getActiveStreamKeys
|
|
};
|