diff --git a/services/capture/src/index.js b/services/capture/src/index.js index 09bccd1..c626f18 100644 --- a/services/capture/src/index.js +++ b/services/capture/src/index.js @@ -10,24 +10,38 @@ const app = express(); const PORT = process.env.PORT || 3001; const MAM_API_URL = process.env.MAM_API_URL || 'http://mam-api:3000'; -// Middleware app.use(cors()); app.use(express.json()); -// Health check app.get('/health', (req, res) => { res.json({ status: 'ok' }); }); -// Routes app.use('/capture', captureRoutes); -// Start server const server = app.listen(PORT, () => { console.log(`Wild Dragon Capture Service listening on port ${PORT}`); bootstrapAutoStart(); }); +// Mapped from the env vars routes/recorders.js writes into the container. +// Empty strings collapse to undefined so capture-manager's defaults win. +function envOpt(name) { + const v = process.env[name]; + return v === undefined || v === '' ? undefined : v; +} +function envInt(name) { + const v = envOpt(name); + if (v === undefined) return undefined; + const n = parseInt(v, 10); + return Number.isFinite(n) ? n : undefined; +} +function envBool(name) { + const v = envOpt(name); + if (v === undefined) return undefined; + return v === 'true' || v === '1' || v === 'yes'; +} + async function bootstrapAutoStart() { const recorderId = process.env.RECORDER_ID; const sourceType = process.env.SOURCE_TYPE; @@ -44,29 +58,42 @@ async function bootstrapAutoStart() { } const listen = process.env.LISTEN === '1' || process.env.LISTEN === 'true'; - const listenPort = process.env.LISTEN_PORT - ? parseInt(process.env.LISTEN_PORT, 10) - : undefined; - const streamKey = process.env.STREAM_KEY || undefined; - const sourceUrl = process.env.SOURCE_URL || undefined; - - if (sourceType === 'sdi') { - console.warn('[bootstrap] SDI auto-start not supported'); - return; - } + const listenPort = envInt('LISTEN_PORT'); + const streamKey = envOpt('STREAM_KEY'); + const sourceUrl = envOpt('SOURCE_URL'); + const device = envInt('DEVICE_INDEX'); console.log(`[bootstrap] starting ${sourceType} ingest (listen=${listen} port=${listenPort || 'n/a'})...`); try { const session = await captureManager.start({ - assetId: process.env.ASSET_ID || null, + assetId: envOpt('ASSET_ID') || null, projectId, - binId: process.env.BIN_ID || null, + binId: envOpt('BIN_ID') || null, clipName, + device, sourceType, sourceUrl, listen, listenPort, streamKey, + + // Recording codec — recorders.js passes these straight through + videoCodec: envOpt('RECORDING_CODEC') || 'prores_hq', + videoBitrate: envOpt('RECORDING_VIDEO_BITRATE'), + framerate: envOpt('RECORDING_FRAMERATE'), + audioCodec: envOpt('RECORDING_AUDIO_CODEC') || 'pcm_s24le', + audioBitrate: envOpt('RECORDING_AUDIO_BITRATE'), + audioChannels: envInt('RECORDING_AUDIO_CHANNELS') ?? 2, + container: envOpt('RECORDING_CONTAINER') || 'mov', + + proxyEnabled: envBool('PROXY_ENABLED') ?? true, + proxyVideoCodec: envOpt('PROXY_CODEC') || 'h264', + proxyVideoBitrate: envOpt('PROXY_VIDEO_BITRATE') || '8M', + proxyFramerate: envOpt('PROXY_FRAMERATE'), + proxyAudioCodec: envOpt('PROXY_AUDIO_CODEC') || 'aac', + proxyAudioBitrate: envOpt('PROXY_AUDIO_BITRATE') || '192k', + proxyAudioChannels: envInt('PROXY_AUDIO_CHANNELS') ?? 2, + proxyContainer: envOpt('PROXY_CONTAINER') || 'mp4', }); console.log(`[bootstrap] session ${session.sessionId} started for clip ${clipName}`); } catch (err) {