HTML:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <!-- 请将页面title修改为你的姓名 -->
    <title>lp</title>
    <style>
        canvas {
            border: 3px solid black;
        }
    </style>
</head>

<body>
    <canvas id="myCanvas" width="600" height="400"></canvas>
    <script src="todo.js"></script>
    <video id ='myvedio' src="video" controls loop hidden width="600" height="300"></video>
</body>

</html>
 JS:
/*
    Functions :代码题-视频弹幕
    Author    :周二班-lp
    Build_Date:2022.11.1
    Version   :1.0
    要求:补充代码来实现demo效果
    1、初始化时显示TXT
    2、鼠标点击开始播放视频
    3、随着视频播放在canvas上逐帧绘制视频内容
    4、播放过程中,按回车键出现弹幕(内容、位置随机)

    说明:
    1、原则上不能大幅修改提供的程序段
    2、在上方Author区注明完成者中文姓名和教学班级,例如“周二班-张三”

 */
//=========================================================================

//=========================变量定义区=======================================
// 此块内容如非必要,请勿修改,可增加或使用该区域变量
let canvas = document.getElementById("myCanvas"),
    context = canvas.getContext('2d');
let video = document.createElement('video');

const W = canvas.width,
    H = canvas.height; // canvas的大小
const TXT = 'Click to Start'; // 初始化时显示的文本
const FPS = 24; // 视频fps
const TXT2 = ['Good', 'Nice', 'Bad', 'Wow']; // 弹幕文字数组

// let danmu = {
//     show: false,
//     txt: '',
//     x0: 0,
//     y0: 0
// }; // 当前弹幕的文字及位置

let playing = true;

let dArray = [];    //弹幕池

//=========================变量定义区 end=======================================


//=========================函数定义区=======================================

//============待完成的代码区域======================
// 请编写函数,绘制每一帧的绘制内容
function drawInterval() {
    // 清屏
    context.clearRect(0, 0, W, H);
    // 绘制视频帧
    //context.drawImage(video, 0, 0, W, H);
    context.save(); //先在底层放图片
    context.globalAlpha = 0.2;
    context.drawImage(video, 0, 0, W, H);   //对于视频元素,是一帧一帧取的
    context.restore();

    context.save();
    //要剪辑的区域形状
    context.beginPath();
    context.arc(W / 2, H / 2, 50, Math.PI / 180 * 0, Math.PI / 180 * 360);
    //剪辑
    context.clip();
    context.drawImage(video, 0, 0, W, H);   //这里对原先的覆盖只会是剪辑的区域进行覆盖
    context.restore();

    // if (danmu.show) {
    //     x -= 20;
    //     context.fillText(danmu.txt, x,danmu.y0);
    // }

    //每播放一帧,就显示之前的全部弹幕
    for (i = 0; i < dArray.length; ++i) //这里不懂
    {
        temp = dArray[i];
        temp.x -= temp.dx;
        //当danmu.show为真是,绘制弹幕
        if (temp.show)
            context.fillText(temp.txt, temp.x, temp.y0);
    }
}




// 请编写函数,开始播放视频并在canvas上逐帧绘制视频
function startAnimation() {
    console.log('播放'); // 此句不要删
    // 开始播放视频
    video.play();   //播放视频之前先写一个play
    // 开始逐帧绘制
    interval = setInterval(drawInterval, 1000 / FPS);   //播放动画
}

function pauseAnimation()
{
    video.pause();  //要暂停视频之前先pause一下video
    clearInterval(interval);    //停止动画
}

// 请编写函数,初始化时显示文本
function showTxt() {
    context.save();
    context.fillStyle='black';
    context.lineWidth=2;
    context.strokeText(TXT, W / 2,H / 2);
    context.restore();
}

// ------ 事件响应函数 ------
// 请编写函数,鼠标点击后开始动画, 鼠标再次点击暂停
canvas.onmousedown = function () {
    playing = !playing;
    if (!playing)
        startAnimation();  
    else
        pauseAnimation();    
}

// 请补全函数,键盘按回车键发送弹幕
window.addEventListener("keydown", function (e) {
    if (e.key == "Enter") {
        console.log("回车键!");
       
        //设置当前弹幕的文本和位置
        var danmu = {
            show: false,
            txt: '',
            x0: 0,
            y0: 0,
            dx: 20,
            x: 0
        }; // 当前弹幕的文字及位置

        danmu.show = true;  //显示为true
        idx = Math.floor(Math.random() * TXT2.length); // 随机从弹幕文本数组中选取一个下标
        // 请补全代码,设置当前弹幕的文本和位置
        danmu.txt=TXT2[idx];
        danmu.x0=Math.random() * W;
        danmu.y0=Math.random() * H;
        danmu.x = danmu.x0;
        //填充弹幕池
        dArray.push(danmu);
    }
});


//============待完成的代码区域 end ====================


//============初始化 ====================
// init,如非必要,请勿修改
function init() {
    console.log('初始化');
    context.font = '60px sans-serif';
    context.textAlign = 'center';
    context.textBaseline = 'middle';
    context.fillStyle = 'red';

    video.src = 'video.mp4';
    video.loop = true;

    showTxt();  //先显示文本
}

//=========================函数定义区 end=======================================
init();