You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js捕获WebSocket MP4视频流保存失败求助:文件无法打开

问题分析

直接把WebSocket收到的原始Buffer写入.webm文件无效,核心原因是WebSocket传输的大概率是未封装的裸视频帧(比如H264/VP8),而非标准WebM容器格式的数据流。WebM需要特定的文件头、元数据和帧时序标记,直接拼接帧数据会破坏文件结构,导致FFmpeg无法识别。

解决方案

1. 先确认流的编码格式

先判断WebSocket返回的视频编码类型,可通过打印Buffer前几个字节识别:

  • VP8帧起始特征:0x9D 0x01 0x2A
  • H264帧起始码:0x00 0x00 0x00 0x01 或 0x00 0x00 0x01

2. 用FFmpeg实时封装成标准WebM

不要直接写Buffer到文件,而是通过管道把WebSocket流传给FFmpeg,让它负责容器封装:

const WebSocket = require('ws');
const { spawn } = require('child_process');
const fs = require('fs');

const ws = new WebSocket('wss://stoa-wsez-e01.ezvds.net/ezs/60/ezugi_5_hd/websocketstream2');
const outputPath = `video_${Date.now()}.webm`;

// 启动FFmpeg,将裸帧封装为WebM
const ffmpeg = spawn('ffmpeg', [
  '-f', 'h264', // 替换为实际编码格式,比如vp8
  '-i', '-', // 从标准输入读取流
  '-c:v', 'copy', // 直接复制编码,避免重新编码
  outputPath
]);

ws.on('open', () => {
  ws.send(JSON.stringify({ eventType: "PLAY", stream: "ezugi_5_hd", requestId: 0 }));
});

ws.on('message', (data) => {
  // 将收到的帧数据写入FFmpeg输入
  ffmpeg.stdin.write(data);
});

ws.on('close', () => {
  // 关闭FFmpeg输入,触发文件写入完成
  ffmpeg.stdin.end();
  ffmpeg.on('exit', () => {
    // 执行截图并删除原视频
    spawn('ffmpeg', [
      '-i', outputPath,
      '-vframes', '1',
      '-ss', '00:00:01',
      `${outputPath}.png`
    ], { stdio: 'inherit' }).on('exit', () => {
      fs.unlinkSync(outputPath);
    });
  });
});

ws.on('error', (err) => {
  console.error('WebSocket错误:', err);
  ffmpeg.kill();
});

注意:如果是H264编码,FFmpeg编译时需要开启WebM兼容H264的选项,若遇到兼容问题,可将输出编码改为VP8(把-c:v copy改成-c:v vp8)。

3. 处理带分隔符的帧数据

如果WebSocket返回的帧前带有长度标识(比如4字节大端长度),需要先解析出完整帧再传给FFmpeg:

let buffer = Buffer.alloc(0);
ws.on('message', (data) => {
  buffer = Buffer.concat([buffer, data]);
  // 按4字节长度标识拆分帧
  while (buffer.length >= 4) {
    const frameLength = buffer.readUInt32BE(0);
    if (buffer.length >= 4 + frameLength) {
      const frame = buffer.slice(4, 4 + frameLength);
      ffmpeg.stdin.write(frame);
      buffer = buffer.slice(4 + frameLength);
    } else {
      break;
    }
  }
});

4. 验证文件有效性

若仍有问题,用ffprobe检查文件结构:

ffprobe video_xxx.webm

如果仍提示Invalid data found when processing input,说明输入格式和FFmpeg的-f参数不匹配,需调整-f的值(比如H264用-f h264,VP8用-f vp8)。

内容的提问来源于stack exchange,提问作者Aleksandr Rogonov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 02:23:32