We all know that the Video TAB allows videos to play in web pages, somewhat replacing Flash. Today we introduce several application scenarios of Video on web pages: variable speed playback, real-time drawing of Video streaming to canvas.
This is the 19th day of my participation in the August Wenwen Challenge.More challenges in August
Variable speed playback
First of all, let’s introduce speed play.
This is actually a built-in function of the browser Video TAB, and does not require developers to do any other Settings or development.
Grammar: videoElement playbackRate = value; 1 indicates normal speed, greater than 1 indicates acceleration, and less than 1 indicates slow speed.
<video src="./video.mp4" controls></video>
var video = document.querySelector("video");
console.log(video.playbackRate);// Get the video playback rate
video.playbackRate = 0.5;// Play at 0.5 speed (slow)
video.playbackRate = 2;// 2 speed playback (speed up)
Copy the code
Draw video streams to canvas in real time
In fact, Canvas provides the ability to draw video content onto canvas.
Here’s an example: The user clicks a button to get the current video image frame data and draws it onto a canvas of the same size.
<button onclick="getCurFrame()">Gets the currently playing video frame</button>
<video src="./video.ogv" controls></video>
<canvas></canvas>
<script>
var video = document.querySelector('video');
var canvas = document.querySelector('canvas');
// Get the width and height of the video when the first frame of the video is loaded
video.onloadeddata = () = >{
canvas.width = video.videoWidth;
canvas.height = video.videoHeight;
}
function getCurFrame(){
const ctx = canvas.getContext('2d');
ctx.drawImage(video,0.0)}</script>
Copy the code
Let’s improve the code a little bit and let the program draw in real time:
function getCurFrame(){
setTimeout(getCurFrame,0)
const ctx = canvas.getContext('2d');
ctx.drawImage(video,0.0)
}
getCurFrame()
Copy the code
We can see that the image on the right canvas is updated in real time, just as the video on the left is playing.
Now we want to replace the light background of the video with a red one. How do we do that? Let’s think about this:
- Each time we draw, we take the image pixels and replace the light background pixels with the ones we want
- The new data is then drawn to the canvas
We just need to add a few lines of code:
let frame = ctx.getImageData(0.0, canvas.width, canvas.height);
// Get the pixel length, each pixel rGBA occupies four positions.
const l = frame.data.length / 4;
for (let i = 0; i < l; i++) {
let r = frame.data[i * 4 + 0];
let g = frame.data[i * 4 + 1];
let b = frame.data[i * 4 + 2];
// Light background pixels. We'll change it to red RGB (255,0,0)
if (g > 100 && r > 100 && b < 43){
frame.data[i*4 + 0] = 255;
frame.data[i*4 + 1] = 0;
frame.data[i*4 + 2] = 0; }}// Redraw the processed frame to the canvas
ctx.putImageData(frame, 0.0);
Copy the code
The effect is as follows:
Record the canvas drawing process and save it
We have converted the video to canvas drawing process, so how to save this process as a new video file?
// Use the Canvas captureStream method and the media recording object MediaRecorder
var stream = canvas.captureStream();
var recorder = new MediaRecorder(stream, { mimeType: 'video/webm' });
var data = [];
recorder.ondataavailable = function (event) {
if(event.data && event.data.size) { data.push(event.data); }}; recorder.onstop =() = > {
// Create a binary object and download it locally with the A tag
var url = URL.createObjectURL(new Blob(data, { type: 'video/webm' }));
const a = document.createElement("a");
a.href = url;
a.download = "video.webm"
a.click();
window.URL.revokeObjectURL(url);
};
video.onplay = () = >{
// Start recording
recorder.start();
}
video.onended = () = >{
// End recording
recorder.stop();
}
Copy the code
After opening the downloaded file, I found an embarrassing problem:
- There’s no audio. This is understandable (because only the footage is recorded)
- I found that the video progress bar could not be dragged. Please refer to the article. Here I use a solution of the open source community
const videoDuration = 1000*20;//(ms单位)
recorder.onstop = () = > {
const buggyBlob = new Blob(data, { type: 'video/webm' });
ysFixWebmDuration(buggyBlob, videoDuration, function(fixedBlob) {
var url = URL.createObjectURL(fixedBlob);
const a = document.createElement("a");
a.href = url;
a.download = "video.webm"
a.click();
window.URL.revokeObjectURL(url);
});
};
Copy the code
The last
Thanks for reading!