我正在构建一个跨平台的Web应用程序,其中音频在服务器上即时生成,并且可能通过HTML5音频元素直播到浏览器客户端.在浏览器上,我将使用Javascript驱动的动画,这些动画必须与播放的音频精确同步."精确"意味着音频和动画必须在彼此之间,并且希望在250ms内(想想唇形同步).由于各种原因,我无法在服务器上进行音频和动画,并对生成的视频进行实时流式传输.
理想情况下,服务器上的音频生成和浏览器上的音频播放之间几乎没有或没有延迟,但我的理解是延迟将难以控制,并且可能在3-7秒范围内(浏览器,环境 - ,网络和月相依赖).但是,我可以处理这个问题,如果我可以在运行中精确测量实际延迟,以便我的浏览器Javascript知道何时呈现正确的动画帧.
那么,我需要精确测量我将音频传输到流媒体服务器(Icecast?)和来自扬声器主机上扬声器的音频之间的延迟.一些蓝天的可能性:
将元数据添加到音频流,并从播放音频中解析它(我知道使用标准音频元素是不可能的)
为音频添加短暂的纯静音时段,然后在浏览器上检测它们(音频元素可以产生实际的音频样本吗?)
查询服务器和浏览器的各种缓冲区深度
在Javascript中解码流式音频,然后获取元数据
有关如何做到这一点的任何想法?
我试图通过缺乏不同的描述来实现离线媒体上下文.
这个概念是创造1秒Blob的录制媒体,具有的能力
Blobs独立播放1秒HTMLMediaElementBlobs 播放完整的媒体资源问题是,一旦Blobs被连接起来,媒体资源就不会HTMLMedia使用a Blob URL或者在元素上播放MediaSource.
创建的Blob URL只播放连接Blob的1秒.MediaSource抛出两个例外
DOMException: Failed to execute 'addSourceBuffer' on 'MediaSource': The MediaSource's readyState is not 'open'
Run Code Online (Sandbox Code Playgroud)
和
DOMException: Failed to execute 'appendBuffer' on 'SourceBuffer': This SourceBuffer has been removed from the parent media source.
Run Code Online (Sandbox Code Playgroud)
如何正确编码连接的Blobs或以其他方式实现变通方法以将媒体片段作为单个重组媒体资源播放?
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<script>
const src = "https://nickdesaulniers.github.io/netfix/demo/frag_bunny.mp4";
fetch(src)
.then(response => response.blob())
.then(blob => …Run Code Online (Sandbox Code Playgroud) 是否有类似XHR的浏览器API可用于通过HTTP将二进制文件流式传输到服务器?
我希望随着时间的推移制作HTTP PUT请求并以编程方式创建数据.我不想一次创建所有这些数据,因为它可能会在内存中出现.一些psueudo代码来说明我所得到的:
var dataGenerator = new DataGenerator(); // Generates 8KB UInt8Array every second
var streamToWriteTo;
http.put('/example', function (requestStream) {
streamToWriteTo = requestStream;
});
dataGenerator.on('data', function (chunk) {
if (!streamToWriteTo) {
return;
}
streamToWriteTo.write(chunk);
});
Run Code Online (Sandbox Code Playgroud)
我现在有一个Web套接字解决方案,但更喜欢常规HTTP,以便更好地与一些现有的服务器端代码互操作.
编辑:我可以使用最前沿的浏览器API.我正在查看Fetch API,因为它支持请求体的ArrayBuffers,DataViews,Files等.如果我能以某种方式伪造其中一个对象,以便我可以使用动态数据的Fetch API,这对我有用.我尝试创建一个Proxy对象,看看是否有任何方法被调用,我可以修补.不幸的是,似乎浏览器(至少在Chrome中)正在使用本机代码而不是JS版本进行读取.但是,如果我错了,请纠正我.
我正在尝试了解节点流及其生命周期.所以,我想分割一个流的内容为n部分.下面的代码只是为了解释我的意图,并表明我已经自己尝试了一些东西.我省略了一些细节
我有一个流,它只生成一些数据(只是一系列数字):
class Stream extends Readable {
constructor() {
super({objectMode: true, highWaterMark: 1})
this.counter = 0
}
_read(size) {
if(this.counter === 30) {
this.push(null)
} else {
this.push(this.counter)
}
this.counter += 1
}
}
const stream = new Stream()
stream.pause();
Run Code Online (Sandbox Code Playgroud)
试图占用下一个块的函数:
function take(stream, count) {
const result = []
return new Promise(function(resolve) {
stream.once('readable', function() {
var chunk;
do {
chunk = stream.read()
if (_.isNull(chunk) || result.length > count) {
stream.pause()
break
}
result.push(chunk)
} while(true)
resolve(result)
})
})
} …Run Code Online (Sandbox Code Playgroud) javascript ×4
bloburls ×1
browser ×1
codec ×1
html5 ×1
html5-audio ×1
http ×1
media ×1
media-source ×1
node.js ×1
streaming ×1