NodeJS 为什么这个读取流没有作为一个明确的结果被发送?

w41d8nur  于 2023-08-04  发布在  Node.js
关注(0)|答案(1)|浏览(103)

我使用ytdl-core来获取音频流,并在我的代码中使用它,如下所示

let stream;
let v_id;

app.get("/ytid/:videoId", function (req, res) {
  let inputVideoID = req.params.videoId;
  getAudio(inputVideoID, res)
    .then(() => {
      stream.pipe(res);
    })
    .catch(err=>{console.log(err);});
});

async function getAudio(videoID, res) {
  if (videoID != v_id) {
    console.log(`getAudio: ${videoID}`);
    stream = ytdl(videoID, {
      quality: "lowestaudio",
      filter: "audioonly",
    });
    v_id = videoID;
  }
}

字符串
但是音频没有被发送。如果我想直接从getAudio()函数管道结果到res,这将是好的,但我想缓存它并将缓存的流发送给多个人。我处理我的流数据的方式有什么问题吗?

ahy6op9u

ahy6op9u1#

node.js中的流是不可重用的。读或写的时候,他们会消耗。也就是说,一旦从流中读取数据一次,就不能再次读取它。因此,不能使用同一个流来处理多个请求
我写了一个从youtube获取音频的例子:

const express = require('express');
const ytdl = require('ytdl-core');
const Stream = require('stream');

let buffer;
let v_id;

const app = express();

app.get("/ytid/:videoId", function (req, res) {
  let inputVideoID = req.params.videoId;
  getAudio(inputVideoID)
  .then((buffer) => {
    const stream = new Stream.PassThrough();
    stream.end(buffer);
    stream.pipe(res);
  })
  .catch(err => {
    console.log(err);
    res.status(500).send(err.message);
  });
});

async function getAudio(videoID) {
  if (videoID !== v_id || !buffer) {
    console.log(`Audio ID: ${videoID}`);
    const stream = ytdl(videoID, {
      quality: "lowestaudio",
      filter: "audioonly",
    });
    buffer = await streamToBuffer(stream);
    v_id = videoID;
  }

  return buffer;
}

function streamToBuffer(stream) {
  return new Promise((resolve, reject) => {
    const chunks = [];
    stream.on('data', chunk => chunks.push(chunk));
    stream.on('end', () => resolve(Buffer.concat(chunks)));
    stream.on('error', reject);
  });
}

const PORT = process.env.PORT || 3000;
app.listen(PORT, () => console.log(`Server is listening on port: ${PORT}`));

字符串


的数据

相关问题