使用Node.js如何将设备视频流推送到AWS IVS等ingestion服务器
问题核心修正点
你当前的代码存在几处关键配置错误,按以下顺序调整即可实现正常推流:
1. 重构FFmpeg参数,避免拆分错误&适配stdin输入
你当前把FFmpeg参数拼成字符串后按空格拆分,会导致x264opts这类带空格的配置被错误拆分,同时输入源配置完全不符合实时流读取逻辑,修正后的配置如下:
const ffmpegArgs = [ // 输入配置:从stdin读webm格式流,不需要本地文件相关参数 '-f', 'webm', '-i', '-', // 视频编码配置,你原来的参数符合IVS要求,保留即可 '-r', '30', '-c:v', 'libx264', '-pix_fmt', 'yuv420p', '-profile:v', 'main', '-preset', 'veryfast', '-x264opts', 'nal-hrd=cbr:no-scenecut', '-minrate', '3000', '-maxrate', '3000', '-g', '60', // 音频编码配置,同样符合IVS要求 '-c:a', 'aac', '-b:a', '160k', '-ac', '2', '-ar', '44100', // 输出格式为flv走rtmps推流 '-f', 'flv', `rtmps://${INGEST_ENDPOINT}:443/app/${STREAM_KEY}` ]; // 启动ffmpeg进程,明确配置stdio const ffmpeg = spawn('ffmpeg', ffmpegArgs, { stdio: ['pipe', 'ignore', 'pipe'] // stdin用于写流,stdout忽略,stderr留着查日志 });
2. 增加FFmpeg进程异常&日志监听
你当前没有监听FFmpeg的输出,出错后无法定位原因,添加以下日志代码:
// 打印FFmpeg运行日志,排查问题必备 ffmpeg.stderr.on('data', (data) => { console.log(`FFmpeg 日志: ${data.toString()}`); }); // 监听进程退出,异常退出时可以自动重启 ffmpeg.on('exit', (code, signal) => { console.log(`FFmpeg 进程退出,退出码: ${code}, 信号: ${signal}`); // 这里可以加进程重启逻辑,避免单次错误导致推流中断 }); ffmpeg.on('error', (err) => { console.error(`FFmpeg 进程启动失败: ${err.message}`); });
3. 修复流写入的背压问题
直接调用write方法可能因为FFmpeg缓冲区满丢数据,调整socket的流写入逻辑:
socket.on("binarystream", (mBuffer) => { // 写入前判断缓冲区是否已满,满了就丢包(实时流丢少量包不影响观感) if (ffmpeg.stdin.writableLength < ffmpeg.stdin.highWaterMark) { ffmpeg.stdin.write(mBuffer, (err) => { if (err) console.error('写入FFmpeg失败:', err); }); } });
4. 前端MediaRecorder配置适配
前端初始化MediaRecorder时明确指定编码格式,避免FFmpeg识别输入格式失败:
// 前端代码,指定输出webm格式,编码为H264+AAC,和后端FFmpeg配置匹配 const mediaRecorder = new MediaRecorder(mediaStream, { mimeType: 'video/webm; codecs="avc1.4D401E,mp4a.40.2"', videoBitsPerSecond: 3000000 // 和后端的3Mbps码率对应,减少转码开销 });
额外注意事项
- 确认AWS IVS的推流密钥和 ingest 端点没有写错,ingest端点不需要带
rtmps://前缀和后缀路径,和你当前的拼接逻辑一致 - 如果需要更低延迟,可以把GOP值改成30(1秒1个关键帧),符合IVS的低延迟配置要求
- 生产环境建议加FFmpeg进程自动重启逻辑,网络抖动导致推流中断时可以自动恢复
内容的提问来源于stack exchange,提问作者rocky
相关产品推荐
相关产品推荐

