如何将Axios获取的实时视频流保存为可播放视频文件?
解决方案:捕获指定时段的实时视频流并保存为可播放文件
基础实现方案(直接操作流)
该方案通过控制流的写入时机和时长,直接将流片段写入文件,适合浏览器可直接播放的标准视频流(如MP4、TS)。
代码示例
const axios = require('axios'); const fs = require('fs'); // 配置参数 const STREAM_URL = 'http://192.168.1.33'; const START_DELAY = 3000; // 延迟X毫秒后开始捕获(对应你需要的指定时间点) const CAPTURE_DURATION = 5000; // 持续捕获5秒 const OUTPUT_FILE = 'captured_video.mp4'; // 根据实际流格式调整后缀(如.ts/.flv) // 创建可写文件流 const writeStream = fs.createWriteStream(OUTPUT_FILE); let isCapturing = false; let stopCaptureTimer; axios.get(STREAM_URL, { responseType: 'stream' }) .then(response => { const stream = response.data; // 延迟指定时间后启动捕获 setTimeout(() => { isCapturing = true; console.log('开始捕获视频流'); // 捕获时长到后停止并清理资源 stopCaptureTimer = setTimeout(() => { isCapturing = false; console.log('捕获结束,正在保存文件'); stream.destroy(); // 关闭响应流 writeStream.end(); // 结束文件写入 }, CAPTURE_DURATION); }, START_DELAY); // 仅在捕获状态下写入文件 stream.on('data', chunk => { if (isCapturing) { writeStream.write(chunk); } }); // 错误处理:避免资源泄漏 stream.on('error', err => { console.error('流读取错误:', err); writeStream.destroy(err); }); writeStream.on('error', err => { console.error('文件写入错误:', err); stream.destroy(); }); }) .catch(err => { console.error('请求视频流失败:', err); writeStream.destroy(err); });
关键说明
- 时间控制:通过两层
setTimeout分别控制捕获的启动时机和结束时机 - 资源清理:停止捕获时必须销毁响应流并结束写入流,确保文件写入完整
- 格式匹配:需根据浏览器中视频的
Content-Type调整输出文件后缀,比如:- 若响应头是
video/mp4,后缀用.mp4 - 若响应头是
video/MP2T,后缀用.ts
- 若响应头是
增强可靠方案(使用FFmpeg处理)
如果直接保存的文件无法播放(比如缺失关键帧或文件头),可以用FFmpeg对流进行封装处理,确保输出文件的可播放性。
代码示例
首先安装依赖:
npm install fluent-ffmpeg
然后编写代码:
const axios = require('axios'); const ffmpeg = require('fluent-ffmpeg'); const STREAM_URL = 'http://192.168.1.33'; const START_DELAY = 3000; const CAPTURE_DURATION = 5000; const OUTPUT_FILE = 'captured_video.mp4'; axios.get(STREAM_URL, { responseType: 'stream' }) .then(response => { const stream = response.data; let ffmpegProcess; setTimeout(() => { console.log('开始捕获并处理视频流'); ffmpegProcess = ffmpeg(stream) .inputFormat('mp4') // 根据实际流格式调整,比如'flv'/'mpegts' .duration(CAPTURE_DURATION / 1000) // 转换为秒数 .output(OUTPUT_FILE) .on('end', () => { console.log('捕获处理完成'); stream.destroy(); }) .on('error', err => { console.error('FFmpeg处理错误:', err); stream.destroy(); }) .run(); // 保险机制:到点强制终止FFmpeg进程 setTimeout(() => { ffmpegProcess?.kill(); }, CAPTURE_DURATION); }, START_DELAY); stream.on('error', err => { console.error('流读取错误:', err); ffmpegProcess?.kill(); }); }) .catch(err => { console.error('请求视频流失败:', err); });
优势
FFmpeg会自动处理视频流的封装、关键帧对齐等问题,输出的文件兼容性和可播放性更强,适合复杂的视频流场景。
内容的提问来源于stack exchange,提问作者VISHAL DAGA
相关产品推荐
相关产品推荐

