node.js - 如何从 nodejs 中的远程 url 创建可读流?

标签 node.js video-streaming nodejs-stream nodejs-server

在 nodejs 文档中,流部分说我可以执行 fs.createReadStream(url || path)。 但是,当我实际这样做时,它告诉我 Error: ENOENT: no such file or directory。 我只想将视频从可读流传输到可写流,但我一直坚持创建可读流。

我的代码:

const express = require('express')
const fs = require('fs')
const url = 'https://www.example.com/path/to/mp4Video.mp4'
const port = 3000

app.get('/video', (req, res) => {
    const readable = fs.createReadStream(url)
})
app.listen(port, () => {
    console.log('listening on port ' + port)
})

错误:

listening on port 3000
events.js:291
      throw er; // Unhandled 'error' event
      ^

Error: ENOENT: no such file or directory, open 'https://www.example.com/path/to/mp4Video.mp4'
Emitted 'error' event on ReadStream instance at:
    at internal/fs/streams.js:136:12
    at FSReqCallback.oncomplete (fs.js:156:23) {
  errno: -2,
  code: 'ENOENT',
  syscall: 'open',
  path: 'https://www.example.com/path/to/mp4Video.mp4'
}

PS:https://www.example.com/path/to/mp4Video.mp4 不是实际网址

最佳答案

fs.createReadStream() 不适用于 http URLs only file:// URLs 或文件名路径。不幸的是,fs 文档中没有对此进行描述,但如果您查看 source code对于 fs.createReadStream() 并按照它调用的内容进行操作,您会发现它最终会调用 fileURULtoPath(url) 如果它不是 file: 网址。

function fileURLToPath(path) {
  if (typeof path === 'string')
    path = new URL(path);
  else if (!isURLInstance(path))
    throw new ERR_INVALID_ARG_TYPE('path', ['string', 'URL'], path);
  if (path.protocol !== 'file:')
    throw new ERR_INVALID_URL_SCHEME('file');
  return isWindows ? getPathFromURLWin32(path) : getPathFromURLPosix(path);
}

建议使用 got() 库从 URL 获取读取流:

const got = require('got');
const mp4Url = 'https://www.example.com/path/to/mp4Video.mp4';

app.get('/video', (req, res) => {
    got.stream(mp4Url).pipe(res);
});

本文中描述的更多示例:How to stream file downloads in Nodejs with Got .


您也可以使用普通的 http/https 模块来获取读取流,但我发现 got() 通常在更高级别对许多 http请求东西,所以这就是我使用的。但是,这是带有 https 模块的代码。

const https = require('https');
const mp4Url = 'https://www.example.com/path/to/mp4Video.mp4';

app.get("/", (req, res) => {
    https.get(mp4Url, (stream) => {
        stream.pipe(res);
    });
});

可以为这两种情况添加更高级的错误处理。

关于node.js - 如何从 nodejs 中的远程 url 创建可读流?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74495753/

相关文章:

node.js - Babel 插件中的 "Visitor.Program.enter()"和 "pre()"有什么区别?

video-streaming - 从 CMSampleBufferRef 获取 sps 和 pps

node.js - 同时播放音频

node.js - Nodejs - 来自 OData $batch 的响应正文状态

node.js - 我想学习如何处理异步代码的 Node js 代码

javascript - 如何让 if 条件看起来更简洁?

node.js - Electron 无法在 Windows 10 上写入文件

node.js - npm对等依赖性 react : can't install any packages

android - 火力地堡存储 : Play back of a video url directly?

command-line - 如何在命令行中使用 VLC 保存视频流?