【发布时间】:2020-09-18 15:59:27
【问题描述】:
总结
我所说的 API
上下文
问题:实际结果+预期结果
我已经尝试过的
帮助你帮助我的线索
最小且可测试的示例:先决条件和要遵循的步骤 + 来源
我所说的 API
https://developer.mozilla.org/en-US/docs/Web/API/MediaRecorder
上下文
我有一个video 元素,我用不同的src 加载和播放了几次。在两个不同的视频之间,会发生过渡,并且每个视频都以淡入显示。播放视频时,我将其绘制在带有过渡和淡入的画布中。
我在画布上绘制的所有内容都是使用 Web API MediaRecorder 记录的。然后我下载这个录音对应的WEBM文件。
问题
实际结果
生成的 WEBM 是生涩的。当我在画布上绘画时,绘画是流畅的。但是画布绘制的记录产生的WEBM是生涩的。
预期结果
由画布绘图记录产生的 WEBM 必须与画布绘图本身一样流畅。如果不可能得到完全这样的结果,那么:WEBM 必须与画布本身一样流畅,我们不能说它是生涩的。
我已经尝试过的
首先,我尝试为媒体记录器的方法
start设置1ms、16ms(对应60fps)、100ms、1000、10000 等时间片,但它没有用。其次,我尝试每 16 毫秒调用一次
requestData(在一个简单的 JS 中,timeoutlistener每 16 毫秒执行一次),但没有成功。
帮助你帮助我的线索
也许我错了,但我的计算机上可能存在材料限制(我有一个没有显卡的 HP Spectre x360,但只有一个小图形芯片),或者我的计算机存在逻辑限制Chromium 浏览器(我的 Ubuntu 16.04 LTS 上的版本为 81.0.4044.138)。
如果您能确认这一点,它将解决这个问题。如果您能解释如何处理这个问题,那就太好了(Web API Media Recorder 的替代解决方案,或其他)。
最小且可测试的示例
先决条件和要遵循的步骤
至少有 2 个 WEBM 视频(这将是输入视频,请记住:我们要输出一个包含画布绘图的新视频,它本身包含这两个输入视频以及过渡和颜色效果等)
拥有一个 HTTP 服务器和一个名为“index.html”的文件,您将使用 Chromium v.81 打开它例如。复制/粘贴以下来源;单击“开始”按钮(您无需单击“停止”按钮);它将在画布上绘制两个视频,带有过渡和颜色效果,它将记录画布绘图,并出现“下载最终输出视频”,允许您下载输出视频。 你会看到它很生涩。
在以下来源中,将视频的路径复制/粘贴到名为
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>
【问题讨论】:
标签: javascript html canvas video web-mediarecorder