从Node到浏览器,不同方式提供和播放wav音频文件的优缺点

3
据我所见,我们可以使用本地的HTMLAudioElementsrc,从Node.js中提供文件或流,并使用本地播放器消费并生成声音。
我们还可以将其分成块(HLS / RTMP),并使用JavaScript播放器消费它,例如hls.jsmediaelement。这将有助于长音频文件(可能很重)的情况,因此我们可以在拥有所有内容之前开始播放。我还看到了一个有趣的项目使用WebSockets
还有其他方法吗?每种方法的利弊是什么?其中任何一种是否具有能够加密所提供内容的“优点”?

1
使用206响应流式传输音频有许多优点(最大的缺点主要是更高的开发和维护工作量)-低初始数据=更好的网站性能,用户可以从稍后的时间开始流式传输,它使“记录”(=下载)音频的部分成为可能,您可以在理论上异步提供块,从而增加服务器性能。也许我会找到一个更全面的摘要,并在接下来的几天内做出回答。 - Jankapunkt
@Jankapunkt 请执行。 - Rikard
2个回答

2
将音频/视频加密可以由您的服务器手动完成。理想情况下,使用流进行加密。
const crypto = require("crypto")
const fs = require("fs")

const browser = getClientConnectionSomehow()

const encryptor = crypto.createCipheriv("aes256", "32 character long string", Buffer.alloc(16))

fs.createReadStream("path/to/video.mp4").pipe(encryptor).pipe(browser)

您可以将视频流发送给客户端。另一种可能更好的方法是让客户端建立WebSocket,客户端请求视频块,服务器使用writeStreams将选定的部分传输到客户端。
我在我的浏览器上进行了快速测试,使用了1分钟的视频和本地主机。它只是将视频传输到客户端,没有限制速度,并且运行得非常好。我没有实现限制速度,但在伪代码中,我会这样做:
客户端:
<video src="/path/to/video">

</video>

let video = document.getElement("video")
WebSocket.send((currentVideoBuffer - video.currentTime) >= 10)
// say, we wait until there are 10 seconds left in the video to load the next chunk.

服务器:
http.createServer((req,res) => {
    let stream = fs.createReadStream("path/to/video.mp4")
    WebSocket.on((shouldSend) => {
        if (shouldSend) {
            res.write(stream.read(500000)
            // just a dummy number of bytes. change as needed.
        }
    })
})

这是极度简化了实际操作方式。在实际应用中,您需要大量改进伪代码才能使其成为可行的选择。但对于音频/视频的直播,这基本上描述了所有后端需求。如果您需要加密,我建议使用此选项,但我不知道浏览器如何解密它,然后将其放入音频元素中。
从nodejs流式传输到客户端相当简单(使用express,只需将res.write连接到FS的readStream的读取函数即可)。
Node是为流内容构建的,并建议查看其原生工具。我还没有研究过您链接的库,但它们似乎是可行的选项。
我认为关键在于您想要多少工具。通过自己的定制实现,您可以添加和删除功能,以创建您梦寐以求的视频/音频播放器。(我确信有一种方法,就像Opus流那样,可以降低某些流的质量,使一些流占用更少的kb/s)。
我认为使用现成的库是最好的起步方式,但如果你的项目围绕流媒体展开,或者你需要类似AES-256或其他非传统算法,那么建议自己实现。正如我上面所演示的,这很复杂,但由于nodejs的存在,也不是太难。
编辑:
我找到了这个NodeJS项目。它是一个视频解析器,可以让你将视频拆分成缓冲区块(并获取缓冲区块的长度!)。这应该有助于您拆分和流式传输缓冲区块。

https://github.com/gkozlenko/node-video-lib


谢谢你的回答!在流中发送的数据类型是什么?加密工具在.pipe(encryptor)中会接收到什么?如果我想改变压缩率,因为用户的网络质量下降了,在这种情况下哪个选项是好的(使用带有压缩的新流或在打开的流内切换压缩)? - Rikard
流的工作方式是“读取”一段数据并进行处理。流被分成多个缓冲区块,可以“读取”它们(写入流也是如此,例如“响应”http对象)。加密工具支持此内置功能,因此您只需将其通过管道传递,并将输出管道传输到写入流中(将其发送到客户端或其他地方)。如果要压缩它,则有一个内置库具有完全相同的功能。https://nodejs.org/dist/latest-v14.x/docs/api/zlib.html#zlib_class_options(您甚至可以更改压缩级别!)(1/2) - Mooshua
从性能角度来看,最好运行几个压缩流(低、中、高),然后将输出拆分到不同的客户端。如果为每个客户端压缩一个结果相同的流,则浪费了计算机资源。如果我没记错的话,您可以将流传输到多个输出(因此,您可以将同一文件的读取流发送到多个http响应)。最好查看nodeJs“stream”模块以获取更多信息 :)(2/2) - Mooshua

-1

我曾经在一个音乐流媒体平台工作。我们需要以流的形式提供高达1-2 GB的音频文件。所以我做了这个。使用ffmpeg库对上传的音频进行格式化处理。你的机器上应该安装了ffmpeg。

require('child_process').exec(`ffmpeg -y -i ${dir_str} -codec copy -bsf:v h264_mp4toannexb -map 0 -f segment -segment_time 10 -segment_format mpegts -segment_list "${m3u8_path}/${soundId}.m3u8" -segment_list_type m3u8 "${m3u8_path}/ts%d.ts"`)

我认为这具有加密的优点。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接