首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在服务器实时节点js中保存我的凸轮流?

如何在服务器实时节点js中保存我的凸轮流?
EN

Stack Overflow用户
提问于 2019-06-29 11:01:06
回答 2查看 3.4K关注 0票数 1

如何实时保存在节点js服务器中转换成块的流块?

我是我的凸轮流,作为二进制到我的节点js服务器

代码语言:javascript
复制
    handleBlobs = async (blob) => {

        let arrayBuffer = await new Response(blob).arrayBuffer()

        let binary = new Uint8Array(arrayBuffer)

        this.postBlob(binary)


    };

 postBlob = blob => {

        axios.post('/api',{blob})
            .then(res => {
                console.log(res)
            })
    };

server.js

代码语言:javascript
复制
app.post('/api', (req, res) => {
    console.log(req.body)
});

如何在视频记录完成后将输入的blobs或二进制文件存储到一个视频文件中。

EN

回答 2

Stack Overflow用户

发布于 2019-07-05 19:23:40

这似乎是How to concat chunks of incoming binary into video (webm) file node js?的重复,但目前还没有一个可接受的答案。我也在把我的答案从那篇文章复制到这篇文章中:

通过使用base64 api将前端转换为FileReader编码,我就能够做到这一点。在后端,从发送的数据块创建一个新的Buffer,并将其写入文件流。在我的代码示例中,一些关键问题是:

  1. 我使用fetch是因为我不想使用axios
  2. 使用fetch时,必须确保在后端使用bodyParser
  3. 我不确定您在块中收集了多少数据(即传递给start对象上的MediaRecorder方法的持续时间值),但是您需要确保后端能够处理传入的数据块的大小。我把我的50MB设得很高,但这可能是不必要的。
  4. 我从不显式地关闭写流..。您可能会在您的/final路由中这样做。否则,createWriteStream默认为AutoClose,因此node进程将自动执行。

以下是完整的工作实例:

前端:

代码语言:javascript
复制
const mediaSource = new MediaSource();
mediaSource.addEventListener('sourceopen', handleSourceOpen, false);
let mediaRecorder;
let sourceBuffer;

function customRecordStream(stream) {
  // should actually check to see if the given mimeType is supported on the browser here.
  let options = { mimeType: 'video/webm;codecs=vp9' };
  recorder = new MediaRecorder(window.stream, options);
  recorder.ondataavailable = postBlob 
  recorder.start(INT_REC)
};

function postBlob(event){
  if (event.data && event.data.size > 0) {
    sendBlobAsBase64(event.data);
  }
}

function handleSourceOpen(event) {
  sourceBuffer = mediaSource.addSourceBuffer('video/webm; codecs="vp8"');
} 

function sendBlobAsBase64(blob) {
  const reader = new FileReader();

  reader.addEventListener('load', () => {
    const dataUrl = reader.result;
    const base64EncodedData = dataUrl.split(',')[1];
    console.log(base64EncodedData)
    sendDataToBackend(base64EncodedData);
  });

  reader.readAsDataURL(blob);
};

function sendDataToBackend(base64EncodedData) {
  const body = JSON.stringify({
    data: base64EncodedData
  });
  fetch('/api', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body
  }).then(res => {
    return res.json()
  }).then(json => console.log(json));
}; 

后端:

代码语言:javascript
复制
const fs = require('fs');
const path = require('path');
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
const server = require('http').createServer(app);

app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json({ limit: "50MB", type:'application/json'}));

app.post('/api', (req, res) => {
  try {
    const { data } = req.body;
    const dataBuffer = new Buffer(data, 'base64');
    const fileStream = fs.createWriteStream('finalvideo.webm', {flags: 'a'});
    fileStream.write(dataBuffer);
    console.log(dataBuffer);
    return res.json({gotit: true});
  } catch (error) {
    console.log(error);
    return res.json({gotit: false});
  }
});
票数 4
EN

Stack Overflow用户

发布于 2019-07-04 11:02:34

在不试图实现这一点的情况下(抱歉,现在没有时间),我建议如下:

  1. 将其读入Node的Stream中,表示请求对象是一个http.IncomingMessage,它是一个可读的Stream。这可以通过管道传输到另一个基于流的API中。consumers
  2. 读入Node的文件系统API,它包含诸如fs.createWriteStream之类的函数,它可以处理块流并附加到文件中,并具有您选择的路径。writestream
  3. 完成文件流后,只要文件名具有正确的扩展名,文件就应该是可播放的,因为通过浏览器发送的缓冲区只是二进制流。进一步阅读Node的缓冲器API是值得您花时间的。buffer
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56817014

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档