Javascript 如何使用MediaRecorder将画布录制为与其他视频完全相同的持续时间?

Javascript 如何使用MediaRecorder将画布录制为与其他视频完全相同的持续时间?,javascript,html5-video,mediarecorder,web-mediarecorder,Javascript,Html5 Video,Mediarecorder,Web Mediarecorder,我有一个持续时间为9200毫秒的视频和一个显示用户网络摄像头视频的画布。我的目标是在播放原始视频的同时录制网络摄像头视频,以创建与MediaRecorder具有完全相同持续时间的输出blob,但似乎总是获得更长长度的视频(通常约9400ms) 我已经发现,如果我在持续时间上的差异,并在输出视频中提前跳过这个量,它基本上会与原始视频同步,但我希望不必使用这种方法。知道了这一点,我认为区别在于HTML5视频的play()函数是异步的,但即使在内部调用recorder.start(),那么play()

我有一个持续时间为9200毫秒的视频和一个显示用户网络摄像头视频的画布。我的目标是在播放原始视频的同时录制网络摄像头视频,以创建与
MediaRecorder
具有完全相同持续时间的输出blob,但似乎总是获得更长长度的视频(通常约9400ms)

我已经发现,如果我在持续时间上的差异,并在输出视频中提前跳过这个量,它基本上会与原始视频同步,但我希望不必使用这种方法。知道了这一点,我认为区别在于HTML5视频的
play()
函数是异步的,但即使在
内部调用
recorder.start()
,那么
play()
承诺之后的
play()
仍然会导致持续时间更长的输出blob

我将
start()
MediaRecorder
放在
play()
ing原始视频之后,并在
requestAnimationFrame
循环中调用
stop()
,当我看到原始视频已结束时。只有在检查原始视频正在播放后,才将
MediaRecorder.start()
更改为在
requestAnimationFrame
循环中开始,这也会导致更长的输出斑点

产出更长的原因可能是什么?从文档中可以看出,
MediaRecorder
的启动或停止功能似乎不是异步的,因此有没有办法保证HTML5视频和
MediaRecorder
的准确启动时间

start()
stop()
是异步的,这就是为什么我们有
onstart
onstop
事件触发:

const stream=makeEmptyStream();
const rec=新媒体记录器(流);
rec.onstart=(evt)=>{console.log(“启动时使用了%sms”,performance.now()-begin);};
const begin=performance.now();
rec.start();
设置超时(()=>{
rec.onstop=(evt)=>{console.log(“停止%sms”,performance.now()-begin);};
const begin=performance.now();
建议停止();
}, 1000 );
函数makeEmptyStream(){
const canvas=document.createElement('canvas');
canvas.getContext('2d').fillRect(0,0,1,1);
返回canvas.captureStream();
}
start()
stop()
是异步的,这就是为什么我们有
onstart
onstop
事件触发:

const stream=makeEmptyStream();
const rec=新媒体记录器(流);
rec.onstart=(evt)=>{console.log(“启动时使用了%sms”,performance.now()-begin);};
const begin=performance.now();
rec.start();
设置超时(()=>{
rec.onstop=(evt)=>{console.log(“停止%sms”,performance.now()-begin);};
const begin=performance.now();
建议停止();
}, 1000 );
函数makeEmptyStream(){
const canvas=document.createElement('canvas');
canvas.getContext('2d').fillRect(0,0,1,1);
返回canvas.captureStream();

}
感谢您的回复!我在CodePen中尝试过这一点,并根据经验发现MediaRecorder对网络摄像头流的捕获始终有0.2秒以上的差异,而对webm视频的捕获通常在[0,0.2]范围内。这是由于媒体设备在捕获时有一定的延迟,还是有办法减少这种延迟?这里的代码笔供参考@JoeyBats运行了两次,得到了34.95和34.977。但是在第二个问题上,我想知道流的帧速率是否与正在记录的内容有关联(从技术上讲,它可以关联,因为他们不会有新的帧推送到记录器,但即使强制
{video:{frameRate:{max:1}}}
我仍然有34.989…仍然可以检查
流.getVideoTracks()[0].getCapabilities().frameRate
来自您的设备?帧速率是一个最大值为30的对象,这似乎没有问题。我发现,对于有声音的视频,我的机器始终有0.2的差异(更新了与上面相同的代码笔以使用有声音的源视频)。但是,如果我禁用选项卡(我使用的是Chrome),记录的持续时间差异非常小(从15.02到15.064)!这是针对我的设备的,还是这实际上会对MediaRecorder产生影响?看到这一点我很惊讶,因为MediaRecorder不是源视频,而是网络摄像头视频…我恐怕无法回答这些问题,而且只有实现者可以…您可能想在Chromium的bug tracker上打开一个问题。O在我的mac OS电脑上,我用你的新代码笔得到了15.087(无论有没有音轨,都没有重大变化…)。是的,我想知道这是否只是设备当前进程的一个功能——我还发现,如果我在单击启动MediaRecord之前向下滚动查看网络摄像头输出,会出现类似的0.1-0.2秒的差异,在mac OS和windows计算机上都得到验证。感谢您的响应!我已经在CodePen和am em中尝试了这一点Piricy发现MediaRecorder对网络摄像头流的捕获始终存在0.2秒以上的差异,而对webm视频的捕获通常在[0,0.2]以内边界。这是媒体设备在捕获过程中有一些延迟的功能,还是有办法减少这种延迟?这里的CodePen供参考@JoeyBats运行了两次,得到了34.95和34.977。但在第二次,我想知道流的帧率是否与正在记录的内容有关(从技术上讲,这是可能的,因为他们不会有新的帧推送到录像机,但即使强制
{video:{frameRate:{max:1}}}
我仍然有34.989…但是,您是否可以检查
流.getVideoTracks()[0].getCapabilities().frameRate
从您的设备?帧速率是一个最大值为30的对象,这似乎没有问题。我发现,对于有声音的视频,我的机器始终有0.2的差异(更新了与上面相同的代码笔,以使用有声音的源视频)