Web API MediaRecorder:如何强制以 60fps 录制?
Web API MediaRecorder: How do I force record at 60fps?
总结
我说的API
上下文
问题:实际结果+预期结果
我已经尝试过的
帮帮我的线索
最小且可测试的示例:要遵循的先决条件和步骤 + 来源
我说的API
https://developer.mozilla.org/en-US/docs/Web/API/MediaRecorder
上下文
我有一个 video
元素,我用不同的 src
加载和播放了几次。在两个不同的视频之间,发生了一个过渡,每个视频都出现了淡入。播放视频时,我将其绘制在 canvas 中,带有过渡和淡入。
我在 canvas 中绘制的所有内容都是使用 Web API MediaRecorder 记录的。然后我下载这个录音对应的WEBM文件
问题
实际结果
生成的 WEBM 不稳定。当我在 canvas 中绘图时,绘图是流畅的。但是 canvas 绘图记录产生的 WEBM 是生涩的。
预期结果
由 canvas 绘图记录产生的 WEBM 必须与 canvas 绘图本身一样流畅。如果不可能得到准确的结果,那么:WEBM 必须大致与 canvas 绘图本身一样流畅,我们不能说它是生涩的。
我已经尝试过的
首先,我尝试给方法[=14=设置了1ms、16ms(对应60fps)、100ms、1000、10000等时间片],但没有用。
其次,我尝试每 16 毫秒调用一次 requestData
(在一个简单的 JS timeoutlistener
每 16 毫秒执行一次),但它没有用。
帮帮我的线索
也许我错了,但我的电脑可能存在 material 限制(我有一台没有显卡的 HP Spectre x360,只有一个小显卡芯片),或我的 Chromium 浏览器的逻辑限制(我的 Ubuntu 16.04 LTS 上有版本 81.0.4044.138)。
如果你能确认这一点,那么这个问题就解决了。如果您能解释如何处理这个问题,那就太好了(Web API Media Recorder 或其他解决方案的替代解决方案)。
最小且可测试的示例
先决条件和要遵循的步骤
至少有 2 个 WEBM 视频(这将是输入视频,记住:我们要输出一个包含 canvas 绘图的新视频,它本身包含这两个输入视频加上过渡和颜色效果等)
有一个 HTTP 服务器和一个名为 "index.html" 的文件,您将使用 Chromium v.81 打开该文件 例如 。 Copy/paste里面有以下来源;单击 "Start" 按钮(您不需要单击 "Stop" 按钮);它会在 canvas 上绘制两个视频,带有过渡和颜色效果,它会记录 canvas 绘图,然后会出现 "Download the final output video",允许您下载输出视频。 你会发现它是生涩的。
在以下来源中,copy/paste 您的视频在名为 videos
的 JS 数组中的路径。
来源
<html>
<head>
<title>Creating Final Video</title>
</head>
<body>
<button id="start">Start</button>
<button id="stop_recording">Stop recording</button>
<video id="video" width="320" height="240" controls>
<source type="video/mp4">
</video>
<canvas id="canvas" width=3200 height=1608></canvas>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script>
var videos = []; // Populated by Selenium
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var video = document.querySelector("video");
startRecording();
$('#start').click(function() {
showSomeMedia(0, 0);
});
function showSomeMedia(videos_counter) {
resetVideo();
if(videos_counter == videos.length) {
$('#stop_recording').click();
return;
} else {
setVideoSrc(videos_counter);
setVideoListener();
videos_counter++;
}
video.addEventListener('ended', () => {
showSomeMedia(videos_counter);
}, false);
}
function resetVideo() {
var clone = video.cloneNode(true);
video.remove();
video = clone;
}
function setVideoSrc(videos_counter) {
video.setAttribute("src", videos[videos_counter]);
video.load();
video.play();
}
function setVideoListener() {
var alpha = 0.1;
video.addEventListener('playing', () => {
function step() {
if(alpha < 1) {
ctx.globalAlpha = alpha;
}
ctx.drawImage(video, 0, 0, canvas.width, canvas.height)
requestAnimationFrame(step)
if(alpha < 1) {
alpha += 0.00001;
}
}
requestAnimationFrame(step);
}, false)
}
function startRecording() {
const chunks = [];
const stream = canvas.captureStream();
const rec = new MediaRecorder(stream);
rec.ondataavailable = e => chunks.push(e.data);
$('#stop_recording').click(function() {
rec.stop();
});
rec.onstop = e => exportVid(new Blob(chunks, {type: 'video/webm'}));
window.setTimeout(function() {
rec.requestData();
}, 1);
rec.start();
}
function exportVid(blob) {
const vid = document.createElement('video');
vid.src = URL.createObjectURL(blob);
vid.controls = true;
document.body.appendChild(vid);
const a = document.createElement('a');
a.download = 'my_final_output_video.webm';
a.href = vid.src;
a.textContent = 'Download the final output video';
document.body.appendChild(a);
}
</script>
</body>
</html>
问题已通过使用我的游戏笔记本电脑 (RoG) 解决,它具有良好的图形卡,能够以比我的 Spectre x360 开发笔记本电脑更高的频率进行记录。
总结
我说的API
上下文
问题:实际结果+预期结果
我已经尝试过的
帮帮我的线索
最小且可测试的示例:要遵循的先决条件和步骤 + 来源
我说的API
https://developer.mozilla.org/en-US/docs/Web/API/MediaRecorder
上下文
我有一个 video
元素,我用不同的 src
加载和播放了几次。在两个不同的视频之间,发生了一个过渡,每个视频都出现了淡入。播放视频时,我将其绘制在 canvas 中,带有过渡和淡入。
我在 canvas 中绘制的所有内容都是使用 Web API MediaRecorder 记录的。然后我下载这个录音对应的WEBM文件
问题
实际结果
生成的 WEBM 不稳定。当我在 canvas 中绘图时,绘图是流畅的。但是 canvas 绘图记录产生的 WEBM 是生涩的。
预期结果
由 canvas 绘图记录产生的 WEBM 必须与 canvas 绘图本身一样流畅。如果不可能得到准确的结果,那么:WEBM 必须大致与 canvas 绘图本身一样流畅,我们不能说它是生涩的。
我已经尝试过的
首先,我尝试给方法[=14=设置了1ms、16ms(对应60fps)、100ms、1000、10000等时间片],但没有用。
其次,我尝试每 16 毫秒调用一次
requestData
(在一个简单的 JStimeoutlistener
每 16 毫秒执行一次),但它没有用。
帮帮我的线索
也许我错了,但我的电脑可能存在 material 限制(我有一台没有显卡的 HP Spectre x360,只有一个小显卡芯片),或我的 Chromium 浏览器的逻辑限制(我的 Ubuntu 16.04 LTS 上有版本 81.0.4044.138)。
如果你能确认这一点,那么这个问题就解决了。如果您能解释如何处理这个问题,那就太好了(Web API Media Recorder 或其他解决方案的替代解决方案)。
最小且可测试的示例
先决条件和要遵循的步骤
至少有 2 个 WEBM 视频(这将是输入视频,记住:我们要输出一个包含 canvas 绘图的新视频,它本身包含这两个输入视频加上过渡和颜色效果等)
有一个 HTTP 服务器和一个名为 "index.html" 的文件,您将使用 Chromium v.81 打开该文件 例如 。 Copy/paste里面有以下来源;单击 "Start" 按钮(您不需要单击 "Stop" 按钮);它会在 canvas 上绘制两个视频,带有过渡和颜色效果,它会记录 canvas 绘图,然后会出现 "Download the final output video",允许您下载输出视频。 你会发现它是生涩的。
在以下来源中,copy/paste 您的视频在名为
videos
的 JS 数组中的路径。
来源
<html>
<head>
<title>Creating Final Video</title>
</head>
<body>
<button id="start">Start</button>
<button id="stop_recording">Stop recording</button>
<video id="video" width="320" height="240" controls>
<source type="video/mp4">
</video>
<canvas id="canvas" width=3200 height=1608></canvas>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script>
var videos = []; // Populated by Selenium
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var video = document.querySelector("video");
startRecording();
$('#start').click(function() {
showSomeMedia(0, 0);
});
function showSomeMedia(videos_counter) {
resetVideo();
if(videos_counter == videos.length) {
$('#stop_recording').click();
return;
} else {
setVideoSrc(videos_counter);
setVideoListener();
videos_counter++;
}
video.addEventListener('ended', () => {
showSomeMedia(videos_counter);
}, false);
}
function resetVideo() {
var clone = video.cloneNode(true);
video.remove();
video = clone;
}
function setVideoSrc(videos_counter) {
video.setAttribute("src", videos[videos_counter]);
video.load();
video.play();
}
function setVideoListener() {
var alpha = 0.1;
video.addEventListener('playing', () => {
function step() {
if(alpha < 1) {
ctx.globalAlpha = alpha;
}
ctx.drawImage(video, 0, 0, canvas.width, canvas.height)
requestAnimationFrame(step)
if(alpha < 1) {
alpha += 0.00001;
}
}
requestAnimationFrame(step);
}, false)
}
function startRecording() {
const chunks = [];
const stream = canvas.captureStream();
const rec = new MediaRecorder(stream);
rec.ondataavailable = e => chunks.push(e.data);
$('#stop_recording').click(function() {
rec.stop();
});
rec.onstop = e => exportVid(new Blob(chunks, {type: 'video/webm'}));
window.setTimeout(function() {
rec.requestData();
}, 1);
rec.start();
}
function exportVid(blob) {
const vid = document.createElement('video');
vid.src = URL.createObjectURL(blob);
vid.controls = true;
document.body.appendChild(vid);
const a = document.createElement('a');
a.download = 'my_final_output_video.webm';
a.href = vid.src;
a.textContent = 'Download the final output video';
document.body.appendChild(a);
}
</script>
</body>
</html>
问题已通过使用我的游戏笔记本电脑 (RoG) 解决,它具有良好的图形卡,能够以比我的 Spectre x360 开发笔记本电脑更高的频率进行记录。