gpt4 book ai didi

node.js - 转码和流式音频 - 如何发送内容范围 header

转载 作者:搜寻专家 更新时间:2023-10-31 23:06:21 28 4
gpt4 key购买 nike

快速版:如何发送正确的Content-Range标题不知道正文长度?

我有一个 FLAC 文件。我想将它转码为 MP3 并立即流式传输给用户。到目前为止,我有这样的事情:

function transcode(file) {
var spawn = require('child_process').spawn

var decode = spawn('flac', [
'--decode',
'--stdout',
file
])

var encode = spawn('lame', [
'-V0',
'-',
'-'
])

decode.stdout.pipe(encode.stdin)

return encode
}

var express = require('express')
var app = express()

app.get('/somefile.mp3', function (req, res) {
res.setHeader('Accept-Ranges', 'bytes')
res.setHeader('Content-Range', 'bytes')
res.setHeader('Content-Type', 'audio/mpeg')
transcode(file).stdout.pipe(res)
})

这按预期工作,但它是“流式传输”,所以我不能跳过。显然我需要做 Content-Range东西。使用:https://github.com/visionmedia/node-range-parser

function sliceStream(start, writeStream, readStream) {
var length = 0
var passed = false

readStream.on('data', function (buf) {
if (passed) return writeStream.write(buf);

length += buf.length

if (length < start) return;

passed = true
writeStream.write(buf.slice(length - start))
})

readStream.on('end', function () {
writeStream.end()
})
}

var parseRange = require('range-parser')

app.get('/somefile.mp3', function (req, res) {
var ranges = parseRange(Infinity, req.headers['range'])

if (ranges === -1 || ranges === -2) return res.send(400);

var start = ranges[0].start

res.setHeader('Accept-Ranges', 'bytes')
res.setHeader('Content-Type', 'audio/mpeg')

if (!start) {
res.setHeader('Content-Range', 'bytes')
transcode(file).stdout.pipe(res)
return
}

res.setHeader('Content-Range', 'bytes ' + start + '-')
sliceStream(start, transcode(file).stdout, res)
})

这就是我卡住的地方。因为我没有等到整首歌都被编码,我不知道这首歌的大小。因为我刚刚在 Chrome 中被“取消”,我假设 Content-Range header 格式不正确,没有大小。

另外,我目前只是在我的浏览器中打开这首歌,所以我假设它使用了 <audio>元素。

建议?

最佳答案

是的,你的 Content-Range header 格式不正确,没有大小。但是,您可以尝试发送您的服务器已经转码的当前大小。尽管我怀疑 Chrome 能否优雅地处理不断变化的大小……

There are a number of things you're not handling :

  1. 您似乎没有发送 206 Partial Content 状态(也许这是由图书馆处理的,不确定)。
  2. 看起来您甚至没有检查范围请求的末尾部分。 Chrome 通常不会发送任何内容,但 0- ,但其他浏览器会。事实上,有些人可能会在单个请求中发送多个范围(支持的皇家痛苦)。
  3. 您没有发送正确的 Content-Range响应 header ,因为您也未能包含您发送的内容的结束索引。它应该是这样的:
    Content-Range: bytes 0-2048/3980841
  4. 最后,如果客户端发出超出范围的范围请求——也就是说,没有任何范围值与资源的范围重叠——服务应该以 416 Requested Range Not Satisfiable 响应。状态。

编辑:我没有测试过这种特殊情况,但如果您从 FLAC 转码为 192kbps CBR MP3,我想如果您正在发送一个稍微不准确的内容长度(相差不到 1000 位):

  • 音频的最后会被播放器剪掉。 ~1000 位会截取大约 5 毫秒 的音频(对人类而言不明显)。
  • 浏览器会忽略结束索引或内容长度,并继续接受和/或请求 Content-Range 之外的范围在您关闭连接或发送 416 状态之前,您最初回复了。
  • 音频的缺失/错误结尾可能会导致 <audio>扔一个MEDIA_ERR_NETWORKMEDIA_ERR_DECODE您只需要优雅地处理的错误。 (在这种情况下,音频仍会被剪辑。)

关于node.js - 转码和流式音频 - 如何发送内容范围 header ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14304642/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com