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

实时录制摄像头视频无时长,无法拖拽跳转问题求助

问题:摄像头实时录制生成的MP4无时长,无法拖拽播放

我搭建了一个服务器端实时录制摄像头的网站,通过WebSocket将摄像头数据传输到Node.js服务器,录制功能正常,但生成的视频没有时长信息,只能逐秒播放,无法拖拽进度条(示例如下):

无法修改进度条示例

服务器保存视频的代码如下:

server.on("connection", (socket) => {
  console.log("Client connected");

  let writeStream = null;
  let id = Date.now();
  let filename = `${folderStream}/video-${id}.${extensionFile}`; // example : ./video/video-1620000000000.mp4

  socket.on("message", (message) => {
    if (!writeStream) {
      console.log("Stream started");
      writeStream = fs.createWriteStream(filename);
    }

    writeStream.write(message);
  });

  socket.on("close", () => {
    console.log("Stream closed");

    writeStream.end();
  });
});

我试过用FFmpeg,但因为是单个完整文件而非分段文件,问题仍未解决,求技术帮助。


核心原因

直接通过WebSocket传输并写入的摄像头数据流,本质是原始的H.264裸流或未完整封装的MP4片段。MP4文件的时长、索引等关键元数据存储在moov原子块中,默认会被写入到文件末尾。但你直接流式写入后关闭文件,播放器无法读取到完整的元数据,因此无法识别时长和支持拖拽操作。

解决方案

方案1:用FFmpeg修复已生成的视频文件

即使是单个完整文件,FFmpeg也能快速重新封装MP4,补全缺失的元数据。执行以下命令:

ffmpeg -i input.mp4 -c copy -movflags faststart output.mp4
  • -c copy:直接复制音视频流,不重新编码,处理速度极快
  • -movflags faststart:将moov原子移到文件开头,同时补全时长等元数据

方案2:实时用FFmpeg转码/封装(推荐)

不要直接写入原始流,而是将WebSocket接收到的数据通过管道传给FFmpeg,让它实时完成标准MP4封装,生成的文件自带完整元数据。

修改Node.js代码示例:

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

server.on("connection", (socket) => {
  console.log("Client connected");

  let id = Date.now();
  let filename = `${folderStream}/video-${id}.mp4`;
  // 启动FFmpeg进程,实时封装MP4
  const ffmpegProcess = spawn('ffmpeg', [
    '-i', '-', // 从标准输入读取原始流
    '-c:v', 'copy', // 复制视频流(需前端传输H.264编码的流)
    '-movflags', 'faststart+frag_keyframe+empty_moov', // 实时分段封装,保证中途可播放
    filename
  ]);

  socket.on("message", (message) => {
    // 将WebSocket数据传给FFmpeg的标准输入
    ffmpegProcess.stdin.write(message);
  });

  socket.on("close", () => {
    console.log("Stream closed");
    // 关闭FFmpeg输入,触发封装收尾
    ffmpegProcess.stdin.end();
    ffmpegProcess.on('exit', () => {
      console.log(`视频文件已生成:${filename}`);
    });
  });

  // 处理FFmpeg的错误输出
  ffmpegProcess.stderr.on('data', (data) => {
    console.error(`FFmpeg错误:${data.toString()}`);
  });
});

注意:如果前端传输的是VP8/VP9等非H.264编码的流,需将参数改为-c:v libx264转码为H.264,保证MP4兼容性。

方案3:前端先做标准封装

如果前端用MediaRecorder录制摄像头流,可配置输出标准MP4格式,减少后端处理压力:

// 前端MediaRecorder配置示例
const mediaRecorder = new MediaRecorder(stream, {
  mimeType: 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"' // 指定H.264+AAC编码
});

前端传输的标准MP4流,后端写入后再用方案1的FFmpeg命令修复即可。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 16:25:24