- Implemented the InternalWHIP component for managing WHIP server configurations. - Added functionality to load live WHIP state from Core and handle OBS URL generation. - Included polling for active streams and notifying parent components of state changes. - Created comprehensive tests for the InternalWHIP component covering various scenarios including fallback mechanisms and state changes. test: add integration tests for WHIP source component - Developed end-to-end tests for the InternalWHIP component to verify its behavior under different configurations. - Ensured that the component correctly handles the loading of WHIP state, displays appropriate messages, and emits the correct onChange events. test: add Settings WHIP configuration tests - Implemented tests for the WHIP settings tab to validate loading and saving of WHIP configurations. - Verified that the correct values are sent back to the Core when the user saves changes. - Ensured that the UI reflects the current state of the WHIP configuration after Core restarts or changes.
98 lines
3.5 KiB
JavaScript
98 lines
3.5 KiB
JavaScript
'use strict';
|
|
const http = require('http');
|
|
const https = require('https');
|
|
const { IngressClient, IngressInput } = require('/home/xesar/WebstormProjects/restreamer-ui-v2/node_modules/livekit-server-sdk');
|
|
|
|
const LK_API_KEY = 'APIBTqTGxf9htMK';
|
|
const LK_API_SECRET = '0dOHWPffwneaPg7OYpe4PeAes21zLJfeYJB9cKzSTtXW';
|
|
const LK_HTTP_URL = 'https://livekit-server.nextream.sytes.net';
|
|
const INGRESS_HOST = '192.168.1.20';
|
|
const INGRESS_PORT = 8088;
|
|
|
|
const sdp = [
|
|
'v=0', 'o=- 0 0 IN IP4 127.0.0.1', 's=-', 't=0 0',
|
|
'm=video 9 UDP/TLS/RTP/SAVPF 96',
|
|
'c=IN IP4 0.0.0.0',
|
|
'a=sendonly', 'a=rtpmap:96 H264/90000', 'a=mid:0',
|
|
].join('\r\n') + '\r\n';
|
|
|
|
function post(path, extraHeaders) {
|
|
return new Promise((resolve, reject) => {
|
|
const req = http.request({
|
|
hostname: INGRESS_HOST, port: INGRESS_PORT,
|
|
path, method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/sdp',
|
|
'Content-Length': Buffer.byteLength(sdp),
|
|
...extraHeaders,
|
|
},
|
|
timeout: 8000,
|
|
}, (r) => {
|
|
let d = '';
|
|
r.on('data', (c) => (d += c));
|
|
r.on('end', () => resolve({ status: r.statusCode, headers: r.headers, body: d.slice(0, 300) }));
|
|
});
|
|
req.on('error', reject);
|
|
req.on('timeout', () => { req.destroy(); reject(new Error('timeout')); });
|
|
req.write(sdp);
|
|
req.end();
|
|
});
|
|
}
|
|
|
|
function options(path) {
|
|
return new Promise((resolve, reject) => {
|
|
const req = http.request({
|
|
hostname: INGRESS_HOST, port: INGRESS_PORT,
|
|
path, method: 'OPTIONS',
|
|
headers: { 'Access-Control-Request-Method': 'POST' },
|
|
timeout: 5000,
|
|
}, (r) => {
|
|
let d = '';
|
|
r.on('data', (c) => (d += c));
|
|
r.on('end', () => resolve({ status: r.statusCode, headers: r.headers, body: d.slice(0, 200) }));
|
|
});
|
|
req.on('error', reject);
|
|
req.on('timeout', () => { req.destroy(); reject(new Error('timeout')); });
|
|
req.end();
|
|
});
|
|
}
|
|
|
|
(async () => {
|
|
console.log(`Conectando a livekit-ingress en ${INGRESS_HOST}:${INGRESS_PORT}\n`);
|
|
|
|
const client = new IngressClient(LK_HTTP_URL, LK_API_KEY, LK_API_SECRET);
|
|
const ingress = await client.createIngress(IngressInput.WHIP_INPUT, {
|
|
name: 'test-direct', roomName: 'test', participantIdentity: 'obs', participantName: 'OBS',
|
|
});
|
|
|
|
const sk = ingress.streamKey;
|
|
console.log('stream_key :', sk);
|
|
console.log('ingress.url:', ingress.url);
|
|
|
|
// OPTIONS
|
|
console.log('\n[OPTIONS /w]');
|
|
const o1 = await options('/w').catch(e => ({ status: 'ERR', body: e.message }));
|
|
console.log(' status:', o1.status, '| allow:', o1.headers?.allow || '-');
|
|
|
|
console.log('\n[OPTIONS /w/' + sk + ']');
|
|
const o2 = await options('/w/' + sk).catch(e => ({ status: 'ERR', body: e.message }));
|
|
console.log(' status:', o2.status, '| allow:', o2.headers?.allow || '-');
|
|
|
|
// POST variants
|
|
const variants = [
|
|
{ label: 'POST /w (sin auth)', path: '/w', headers: {} },
|
|
{ label: 'POST /w/'+sk+' (sk en URL)', path: '/w/'+sk, headers: {} },
|
|
{ label: 'POST /w Bearer sk', path: '/w', headers: { Authorization: 'Bearer ' + sk } },
|
|
{ label: 'POST /w/'+sk+' Bearer sk (sk en URL + auth)', path: '/w/'+sk, headers: { Authorization: 'Bearer ' + sk } },
|
|
];
|
|
|
|
for (const v of variants) {
|
|
console.log('\n[' + v.label + ']');
|
|
const r = await post(v.path, v.headers).catch(e => ({ status: 'ERR', body: e.message }));
|
|
console.log(' status:', r.status, '| body:', r.body?.slice(0, 120));
|
|
}
|
|
|
|
await client.deleteIngress(ingress.ingressId).catch(() => {});
|
|
console.log('\nIngress eliminado.');
|
|
})().catch((e) => { console.error(e.message); process.exit(1); });
|