From 8b936130df8e5fafae3398548f56a0583a2f7151 Mon Sep 17 00:00:00 2001 From: CN-JS-HuiBai Date: Fri, 3 Apr 2026 17:53:05 +0800 Subject: [PATCH] add support for rkmpp --- README.md | 1 + public/index.html | 1 + server.js | 19 ++++++++++++------- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 6eb973c..958a9f9 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,7 @@ To properly test and run this project, you will need to prepare your environment 1. **Install Node.js & FFmpeg**: - Ensure Node.js (v18+) is installed. - Install **FFmpeg** on your system and make sure it is available in your PATH environment variable. The Node.js library `fluent-ffmpeg` requires it. + - If you plan to use Rockchip hardware encoding, make sure your FFmpeg build includes `h264_rkmpp` / `hevc_rkmpp` support and the device has the Rockchip MPP runtime available. 2. **AWS S3 / MinIO Configuration**: - Modify the `.env` file (copy from `.env.example`). diff --git a/public/index.html b/public/index.html index 2809741..92b9b7e 100644 --- a/public/index.html +++ b/public/index.html @@ -68,6 +68,7 @@ +
diff --git a/server.js b/server.js index f5a5417..984b5a1 100644 --- a/server.js +++ b/server.js @@ -95,15 +95,17 @@ const broadcastWs = (key, payload) => { }; const createFfmpegOptions = (encoderName) => { - const options = ['-preset fast']; + const options = []; if (encoderName === 'libx264' || encoderName === 'libx265') { - options.push('-crf', '23', '-threads', '0'); + options.push('-preset', 'fast', '-crf', '23', '-threads', '0'); } else if (/_nvenc$/.test(encoderName)) { - options.push('-rc:v', 'vbr_hq', '-cq', '19'); + options.push('-preset', 'fast', '-rc:v', 'vbr_hq', '-cq', '19'); } else if (/_qsv$/.test(encoderName)) { - options.push('-global_quality', '23'); + options.push('-preset', 'fast', '-global_quality', '23'); } else if (/_vaapi$/.test(encoderName)) { options.push('-qp', '23'); + } else if (/_rkmpp$/.test(encoderName)) { + options.push('-qp_init', '23', '-pix_fmt', 'nv12'); } return options; }; @@ -146,6 +148,8 @@ const getSeekFriendlyOutputOptions = (encoderName, metadata) => { options.push('-forced-idr', '1', '-force_key_frames', 'expr:gte(t,n_forced*2)'); } else if (/_qsv$/.test(encoderName)) { options.push('-idr_interval', '1'); + } else if (/_rkmpp$/.test(encoderName)) { + options.push('-force_key_frames', 'expr:gte(t,n_forced*2)'); } return options; @@ -153,7 +157,7 @@ const getSeekFriendlyOutputOptions = (encoderName, metadata) => { const shouldRetryWithSoftware = (message) => { if (!message) return false; - return /Cannot load libcuda\.so\.1|Could not open encoder before EOF|Error while opening encoder|Operation not permitted|Invalid argument/i.test(message); + return /Cannot load libcuda\.so\.1|Could not open encoder before EOF|Error while opening encoder|Operation not permitted|Invalid argument|mpp_create|rkmpp/i.test(message); }; const probeFile = (filePath) => { @@ -392,13 +396,14 @@ app.get('/api/stream', async (req, res) => { } const safeCodec = codec === 'h265' ? 'h265' : 'h264'; - const safeEncoder = ['nvidia', 'intel', 'vaapi', 'neon'].includes(encoder) ? encoder : 'software'; + const safeEncoder = ['nvidia', 'intel', 'vaapi', 'rkmpp', 'neon'].includes(encoder) ? encoder : 'software'; const codecMap = { software: { h264: 'libx264', h265: 'libx265' }, neon: { h264: 'libx264', h265: 'libx265' }, nvidia: { h264: 'h264_nvenc', h265: 'hevc_nvenc' }, intel: { h264: 'h264_qsv', h265: 'hevc_qsv' }, - vaapi: { h264: 'h264_vaapi', h265: 'hevc_vaapi' } + vaapi: { h264: 'h264_vaapi', h265: 'hevc_vaapi' }, + rkmpp: { h264: 'h264_rkmpp', h265: 'hevc_rkmpp' } }; const videoCodec = codecMap[safeEncoder][safeCodec];