feat(recorders): add PortBindings for SRT/RTMP listener mode containers
When source_config.mode === 'listener': - SRT: bind UDP listen_port (default 9000) on container host - RTMP: bind TCP listen_port (default 1935) on container host Add ExposedPorts to container config alongside HostConfig.PortBindings. Also pass LISTEN, LISTEN_PORT, STREAM_KEY env vars to container.
This commit is contained in:
parent
55fec605c6
commit
78b1f3482f
1 changed files with 70 additions and 18 deletions
|
|
@ -46,6 +46,31 @@ function generateClipName(recorderName) {
|
|||
return `${recorderName}_${year}${month}${day}_${hours}${minutes}${seconds}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build Docker PortBindings and ExposedPorts for listener-mode recorders.
|
||||
* Returns { portBindings, exposedPorts } — both empty objects for non-listener sources.
|
||||
*/
|
||||
function buildPortConfig(sourceType, sourceConfig) {
|
||||
const portBindings = {};
|
||||
const exposedPorts = {};
|
||||
|
||||
if (sourceConfig && sourceConfig.mode === 'listener') {
|
||||
if (sourceType === 'srt') {
|
||||
const port = String(sourceConfig.listen_port || 9000);
|
||||
const proto = `${port}/udp`;
|
||||
portBindings[proto] = [{ HostPort: port }];
|
||||
exposedPorts[proto] = {};
|
||||
} else if (sourceType === 'rtmp') {
|
||||
const port = String(sourceConfig.listen_port || 1935);
|
||||
const proto = `${port}/tcp`;
|
||||
portBindings[proto] = [{ HostPort: port }];
|
||||
exposedPorts[proto] = {};
|
||||
}
|
||||
}
|
||||
|
||||
return { portBindings, exposedPorts };
|
||||
}
|
||||
|
||||
// GET / - List all recorders
|
||||
router.get('/', async (req, res, next) => {
|
||||
try {
|
||||
|
|
@ -172,30 +197,57 @@ router.post('/:id/start', async (req, res, next) => {
|
|||
// Generate clip name with timestamp
|
||||
const clipName = generateClipName(recorder.name);
|
||||
|
||||
// Determine source config and whether this is a listener-mode recorder
|
||||
const sourceConfig = recorder.source_config || {};
|
||||
const isListener = sourceConfig.mode === 'listener';
|
||||
const sourceType = recorder.source_type;
|
||||
|
||||
// Build port bindings for listener-mode SRT/RTMP containers
|
||||
const { portBindings, exposedPorts } = buildPortConfig(sourceType, sourceConfig);
|
||||
|
||||
// Build container environment — pass all source params so the capture
|
||||
// service can auto-start recording on container startup
|
||||
const env = [
|
||||
`S3_ENDPOINT=${s3Endpoint}`,
|
||||
`S3_BUCKET=${s3Bucket}`,
|
||||
`S3_ACCESS_KEY=${s3AccessKey}`,
|
||||
`S3_SECRET_KEY=${s3SecretKey}`,
|
||||
`S3_REGION=${process.env.S3_REGION || 'us-east-1'}`,
|
||||
`MAM_API_URL=${mamApiUrl}`,
|
||||
`RECORDER_ID=${id}`,
|
||||
`SOURCE_TYPE=${sourceType}`,
|
||||
`SOURCE_CONFIG=${JSON.stringify(sourceConfig)}`,
|
||||
`RECORDING_CODEC=${recorder.recording_codec}`,
|
||||
`RECORDING_RESOLUTION=${recorder.recording_resolution}`,
|
||||
`PROXY_ENABLED=${recorder.proxy_enabled}`,
|
||||
`PROXY_CODEC=${recorder.proxy_codec}`,
|
||||
`PROXY_RESOLUTION=${recorder.proxy_resolution}`,
|
||||
`PROJECT_ID=${recorder.project_id}`,
|
||||
`CLIP_NAME=${clipName}`,
|
||||
];
|
||||
|
||||
// Add source-specific env vars for SRT/RTMP
|
||||
if (sourceType === 'srt' || sourceType === 'rtmp') {
|
||||
env.push(`LISTEN=${isListener ? '1' : '0'}`);
|
||||
if (isListener) {
|
||||
env.push(`LISTEN_PORT=${sourceConfig.listen_port || (sourceType === 'srt' ? 9000 : 1935)}`);
|
||||
if (sourceType === 'rtmp' && sourceConfig.stream_key) {
|
||||
env.push(`STREAM_KEY=${sourceConfig.stream_key}`);
|
||||
}
|
||||
} else if (sourceConfig.url) {
|
||||
env.push(`SOURCE_URL=${sourceConfig.url}`);
|
||||
}
|
||||
}
|
||||
|
||||
// Build container config
|
||||
const containerConfig = {
|
||||
Image: 'wild-dragon-capture:latest',
|
||||
Env: [
|
||||
`S3_ENDPOINT=${s3Endpoint}`,
|
||||
`S3_BUCKET=${s3Bucket}`,
|
||||
`S3_ACCESS_KEY=${s3AccessKey}`,
|
||||
`S3_SECRET_KEY=${s3SecretKey}`,
|
||||
`S3_REGION=${process.env.S3_REGION || 'us-east-1'}`,
|
||||
`MAM_API_URL=${mamApiUrl}`,
|
||||
`RECORDER_ID=${id}`,
|
||||
`SOURCE_TYPE=${recorder.source_type}`,
|
||||
`SOURCE_CONFIG=${JSON.stringify(recorder.source_config)}`,
|
||||
`RECORDING_CODEC=${recorder.recording_codec}`,
|
||||
`RECORDING_RESOLUTION=${recorder.recording_resolution}`,
|
||||
`PROXY_ENABLED=${recorder.proxy_enabled}`,
|
||||
`PROXY_CODEC=${recorder.proxy_codec}`,
|
||||
`PROXY_RESOLUTION=${recorder.proxy_resolution}`,
|
||||
`PROJECT_ID=${recorder.project_id}`,
|
||||
`CLIP_NAME=${clipName}`,
|
||||
],
|
||||
Env: env,
|
||||
ExposedPorts: Object.keys(exposedPorts).length > 0 ? exposedPorts : undefined,
|
||||
HostConfig: {
|
||||
Privileged: true,
|
||||
NetworkMode: dockerNetwork,
|
||||
PortBindings: Object.keys(portBindings).length > 0 ? portBindings : undefined,
|
||||
},
|
||||
Hostname: `recorder-${recorder.name.toLowerCase().replace(/[^a-z0-9]/g, '-')}`,
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in a new issue