如何在 nodejs 中从远程 url 创建可读流?
how to create a readable stream from a remote url in nodejs?
在 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 IS NOT THE ACTUAL URL
fs.createReadStream()
不适用于 http URLs only file://
URLs 或文件名路径。不幸的是,fs
文档中没有对此进行描述,但是如果您查看 fs.createReadStream()
的 source code 并按照它的调用进行操作,您会发现它最终会调用 fileURULtoPath(url)
如果它不是 file:
URL.
就会抛出
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);
});
});
可以为这两种情况添加更高级的错误处理。
在 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 IS NOT THE ACTUAL URL
fs.createReadStream()
不适用于 http URLs only file://
URLs 或文件名路径。不幸的是,fs
文档中没有对此进行描述,但是如果您查看 fs.createReadStream()
的 source code 并按照它的调用进行操作,您会发现它最终会调用 fileURULtoPath(url)
如果它不是 file:
URL.
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);
});
});
可以为这两种情况添加更高级的错误处理。