Adiciona suporte a encoders de hardware (NVENC, VAAPI, QSV) no ffmpeg
---
- Implementada função buildEncoderFlags() em supervisor.ts e reprovision.mjs que gera o bloco de flags do ffmpeg conforme a env var FFMPEG_HWACCEL (nvenc, vaapi, qsv ou vazio para libx264);
- Template stream.template.conf refatorado para usar {{ENCODER_FLAGS}} no lugar do bloco x264 fixo;
- NVENC configurado com perfil high, mapeamento de presets x264→p1-p7 e tune zerolatency→ll;
- docker-compose.yml atualizado com seções comentadas para gpus, devices, FFMPEG_HWACCEL e instrução de volume WSL2 para libnvidia-encode;
- Dockerfile adiciona mesa-va-drivers e intel-media-va-driver para suporte a VAAPI e remove declaração VOLUME redundante;
- fetchAllStatuses() corrigido: supervisorctl status || true evita exceção com exit code 3 quando há processos parados;
- reprovision.mjs atualizado para incluir AUTO_RELOAD e AUTO_RELOAD_INTERVAL no contexto de renderização do template;
---
This commit is contained in:
@@ -23,6 +23,70 @@ function render(tpl, vars) {
|
||||
return tpl.replace(/\{\{(\w+)\}\}/g, (_, k) => String(vars[k] ?? ''))
|
||||
}
|
||||
|
||||
const NVENC_PRESET = {
|
||||
ultrafast: 'p1', superfast: 'p1', veryfast: 'p2',
|
||||
faster: 'p3', fast: 'p3', medium: 'p4',
|
||||
slow: 'p5', slower: 'p6', veryslow: 'p7',
|
||||
}
|
||||
|
||||
function buildEncoderFlags(stream) {
|
||||
const { preset, tune, gop, bitrate, bufsize } = stream
|
||||
const hwaccel = (process.env.FFMPEG_HWACCEL ?? '').toLowerCase().trim()
|
||||
const lines = []
|
||||
const ln = (s) => lines.push(` ${s} \\`)
|
||||
|
||||
if (hwaccel === 'nvenc') {
|
||||
ln(`-c:v h264_nvenc`)
|
||||
ln(`-preset ${NVENC_PRESET[preset] ?? 'p4'}`)
|
||||
ln(`-tune ${tune === 'zerolatency' ? 'll' : 'hq'}`)
|
||||
ln(`-profile:v high`)
|
||||
ln(`-pix_fmt yuv420p`)
|
||||
ln(`-rc cbr`)
|
||||
ln(`-g ${gop}`)
|
||||
ln(`-keyint_min ${gop}`)
|
||||
ln(`-b:v ${bitrate}`)
|
||||
ln(`-maxrate ${bitrate}`)
|
||||
ln(`-bufsize ${bufsize}`)
|
||||
} else if (hwaccel === 'vaapi') {
|
||||
ln(`-vaapi_device /dev/dri/renderD128`)
|
||||
ln(`-vf 'format=nv12,hwupload'`)
|
||||
ln(`-c:v h264_vaapi`)
|
||||
ln(`-profile:v baseline`)
|
||||
ln(`-level 3.1`)
|
||||
ln(`-g ${gop}`)
|
||||
ln(`-keyint_min ${gop}`)
|
||||
ln(`-b:v ${bitrate}`)
|
||||
ln(`-maxrate ${bitrate}`)
|
||||
ln(`-bufsize ${bufsize}`)
|
||||
} else if (hwaccel === 'qsv') {
|
||||
ln(`-c:v h264_qsv`)
|
||||
ln(`-preset veryfast`)
|
||||
ln(`-profile:v baseline`)
|
||||
ln(`-level 3.1`)
|
||||
ln(`-pix_fmt nv12`)
|
||||
ln(`-g ${gop}`)
|
||||
ln(`-keyint_min ${gop}`)
|
||||
ln(`-b:v ${bitrate}`)
|
||||
ln(`-maxrate ${bitrate}`)
|
||||
ln(`-bufsize ${bufsize}`)
|
||||
} else {
|
||||
ln(`-c:v libx264`)
|
||||
ln(`-preset ${preset}`)
|
||||
ln(`-tune ${tune}`)
|
||||
ln(`-profile:v baseline`)
|
||||
ln(`-level 3.1`)
|
||||
ln(`-pix_fmt yuv420p`)
|
||||
ln(`-g ${gop}`)
|
||||
ln(`-keyint_min ${gop}`)
|
||||
ln(`-sc_threshold 0`)
|
||||
ln(`-b:v ${bitrate}`)
|
||||
ln(`-maxrate ${bitrate}`)
|
||||
ln(`-bufsize ${bufsize}`)
|
||||
}
|
||||
|
||||
return lines.join('\n')
|
||||
}
|
||||
|
||||
for (const stream of streams) {
|
||||
const dir = path.join(STREAMS_DIR, stream.id)
|
||||
fs.mkdirSync(path.join(dir, 'chrome-profile'), { recursive: true })
|
||||
@@ -49,6 +113,7 @@ for (const stream of streams) {
|
||||
USER: stream.user ?? '',
|
||||
PASS: stream.pass ?? '',
|
||||
GPU_FLAGS: stream.gpu ? '' : ' --disable-gpu \\\n',
|
||||
ENCODER_FLAGS: buildEncoderFlags(stream),
|
||||
AUTO_RELOAD: stream.autoReload ? 'true' : 'false',
|
||||
AUTO_RELOAD_INTERVAL: stream.autoReloadInterval ?? 3600,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user