如何使用JavaScript分块上传视频并将视频保存为express?

问题描述 投票:0回答:1

最终我想对客户端的用户视频进行调整,但现在我只是想看看如何分解视频并将数据分块发送到我的快速服务器并保存文件。目前我可以在我的服务器上保存一个视频文件,但我认为数据已损坏,因为它实际上无法播放。

这是我的 Web 客户端 JavaScript:

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

function arrBuffToBase64( buffer ) {
    let binary = '';
    const bytes = new Uint8Array( buffer );
    const len = bytes.byteLength;
    for (let i = 0; i < len; i++) {
        binary += String.fromCharCode( bytes[ i ] );
    }
    return window.btoa( binary );
}

const sendArrBuffToBackend = arrayBuffer => {
    console.debug('sendArrBuffToBackend', arrayBuffer)
    return sendDataToBackend(arrBuffToBase64(arrayBuffer));
}

const readBlob = (file, startByte, endByte) => {
    const start = startByte || 0;
    const end = endByte || file.size;
    const reader = new FileReader();
    const blob = file.slice(start, end);
    console.debug('readBlob', start, end)

    reader.readAsArrayBuffer(blob);

    return new Promise((res, rej) => {
        reader.onloadend = function (event) {
            if (event.target.readyState === FileReader.DONE) {
                // Data has been read, invoke the complete method!
                res(event.target.result);
            }
        };

        reader.onerror = function (event) {
            rej(event.target.error.code);
        }
    })
};

const clone = async (file, start, end, onData) => {
    console.debug('cloning', { start, end });

    let currStart = start;
    let currEnd = start + CHUNK_SIZE;
    do {
        await onData(await readBlob(file, currStart, Math.min(currEnd, end)))
        currStart = currEnd + 1;
        currEnd = currStart + CHUNK_SIZE;
    } while (currEnd < end)
}

// this function is added to file input onchange
window.process = async function(fileInput) {
    const file = fileInput.files[0]
    await clone(file, 0, file.size, sendArrBuffToBackend)
}

快递代码:

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

app.post('/upload', (req, res) => {
    try {
        const {data} = req.body;
        const dataBuffer = new Buffer(data, 'base64');
        const fileStream = fs.createWriteStream('faststart.mp4', {flags: 'a'});
        fileStream.write(dataBuffer);
        console.log(dataBuffer);
        return res.json({gotIt: true});
    } catch (error) {
        console.log(error);
        return res.json({gotIt: false});
    }
})
javascript node.js web upload arraybuffer
1个回答
0
投票
enter code here

尝试{ console.log("req",req.body)

let response = { status: false, message: 'Failed to open video file' };
    
  
 const videoPath = path.join(__dirname, 'public');
 // console.log("videoPath",videoPath)
  const mediaId = req.body.media_id
  let media_path =req.body.media_url
  let chunk_size = req.body.chenk_size
  // let total_size =parseInt(event.body.total_size)
 // let media_path = videoPath + '/a5475c64-e848-4adb-ac33-25a779f2303e.mp4'
  // event.body.media_url
  //__dirname + '/a5475c64-e848-4adb-ac33-25a779f2303e.mp4'
  console.log("media_path",media_path)
  
  if (!fs.existsSync(videoPath)) {
     fs.mkdirSync(videoPath, { recursive: true });
 }
 
 const videoMediaPath = path.join(__dirname, 'public',mediaId);

 if (!fs.existsSync(videoMediaPath)) {
     fs.mkdirSync(videoMediaPath, { recursive: true });
 }else{
  // Clean directory
  fs.readdirSync(videoMediaPath).forEach((file) => {
     const filePath = path.join(videoMediaPath, file);
     fs.unlinkSync(filePath);
 });
 }

  const chunkSize = parseInt(chunk_size) * 1024 * 1024; // 30MB
  const sourceFile = fs.openSync(media_path, 'r');
  
  if (sourceFile) {
      let i = 1;
      let chunkFileList = [];
      const buffer = Buffer.alloc(chunkSize);
      let bytesRead;
      
      while ((bytesRead = fs.readSync(sourceFile, buffer, 0, chunkSize, null)) > 0) {
          const chunkFileName = path.join(videoMediaPath, `chunk_${i}.mp4`);
          fs.writeFileSync(chunkFileName, buffer.slice(0, bytesRead));
          chunkFileList.push(chunkFileName);
          i++;
      }

      fs.closeSync(sourceFile);

      // Sort chunk files by creation time
      chunkFileList.sort((a, b) => {
          return fs.statSync(a).ctimeMs - fs.statSync(b).ctimeMs;
      });

      console.log("chunkFileList",chunkFileList)

      console.log('video splitting =>', media_path, 'media_upload', 'response');
      response = { status: true, message: 'Media splitting successfully', files: chunkFileList };
      res.send(response)
  }
  
  }catch(err){
     throw new Error(err)
  }[enter link description here][1]
© www.soinside.com 2019 - 2024. All rights reserved.