Canvas替换webRtc视频流

发布于:2024-04-08 ⋅ 阅读:(139) ⋅ 点赞:(0)

默认关闭摄像头画面就是全黑,准备做一个canvas绘制头像,当关闭摄像头时传入canvas绘制名字头像;

核心api可以把canvas生成stram对象
canvas.captureStream();
业务代码canvas生成头像
export class CanvasToStram{
    animationId: any;
    // 头像名称
    userName: string;
    // canvas
    myCanvas: HTMLCanvasElement;
    constructor(userName: string) {
        this.animationId = null;
        this.userName = userName;
        this.myCanvas = document.createElement('canvas');
        this.drawAvatar = this.drawAvatar.bind(this);
    }
    start() {
        if (this.animationId) {
            // 当你想要取消动画时
            cancelAnimationFrame(this.animationId);
            this.animationId = null;
        }
        this.drawAvatar();
        /* 返回canvas生成的媒体流 */
        return Promise.resolve(this.myCanvas.captureStream());
    }
    stop() {
        if (this.animationId) {
            // 当你想要取消动画时
            cancelAnimationFrame(this.animationId);
            this.animationId = null;
        }
        return Promise.resolve();
    }
    drawAvatar() {
        console.log('xxx');
        let userName = this.userName;
        let context = this.myCanvas.getContext('2d');
        /* 整体背景 */
        this.myCanvas.width = 1280;
        this.myCanvas.height = 720;
        context.fillStyle = '#1C1C1C';
        context.clearRect(0, 0, 1280, 720);
        context.fillRect(0, 0, 1280, 720);
        /* 绘制圆角-start */
        context.beginPath(); //开始绘制路径
        context.lineWidth = 5; //边框大小
        // 起始点:moveTo(x,y) 二次贝塞尔曲线:quadraticCurveTo('控制点x','控制点y','结束点x','结束点y') 结束点:lineTo(x,y) ;
        let x = 590;
        let y = 310;
        let width = 100;
        let height = 100;
        let radius = 10;
        context.moveTo(x+radius,y);
        context.lineTo(x+width-radius,y);
        context.quadraticCurveTo(x+width, y, x+width, y+radius);
        context.lineTo(x+width,y+height-radius);
        context.quadraticCurveTo(x+width, y+height, x+width-radius, y+height);
        context.lineTo(x+radius,y+height);
        context.quadraticCurveTo(x, y+height, x, y+height-radius);
        context.lineTo(x,y+radius);
        context.quadraticCurveTo(x, y, x+radius, y);
        context.fillStyle ="#1677FF"; //为圆角矩形填充颜色
        context.strokeStyle="#1677FF"; //矩形边框颜色
        context.closePath(); //闭合绘制的路径
        context.fill(); //填充当前的路径,默认颜色是黑色
        // context.stroke(); //绘制确切的路径
         /* 绘制圆角-end */
        // 头像字体颜色设置
        context.fillStyle = '#fff';
        context.font = 'normal' + ' bold' + ' ' + 30 + 'px Arial,sans-serif';
        context.textAlign = 'center';
        context.textBaseline = 'middle';
        context.fillText(userName.slice(0, 1), 640, 360);
        // 全名
        context.fillStyle = '#fff';
        context.font = 'normal' + ' bold' + ' ' + 30 + 'px Arial,sans-serif';
        context.textAlign = 'center';
        context.textBaseline = 'middle';
        context.fillText(userName, 640, 450);

        this.animationId = requestAnimationFrame(this.drawAvatar);
    }
    
    // 录制canvas并下载为mp4
    recordCanvas() {
        let stream = this.myCanvas.captureStream();
        const mimeType = 'video/webm;codecs=h264';
        let recorder = new MediaRecorder(stream, { mimeType:mimeType });
        const data = []
        recorder.ondataavailable = function(event){
            if(event?.data.size) data.push(event.data);
        }
        recorder.onstop = () => {
            let url = URL.createObjectURL(new Blob(data, { type: MediaRecorder.isTypeSupported("video/webm;codecs=h264") ? 'video/mp4' : data[0].type }));
            let a = document.createElement('a');
            a.href = url;
            /* 如果浏览器支持video/webm;codecs=h264的话, 可以直接修改文件后缀名.mp4 可以下载mp4 */
            a.download = MediaRecorder.isTypeSupported("video/webm;codecs=h264") ? 'video.mp4' : 'video.webm';
            a.click();
        }
        recorder.start(0);
        /* 测试录制1秒后停止 */
        setTimeout(() => {
            recorder.stop();
        }, 1000);
}
}
使用
const myCanvasToStram  = new CanvasToStram(account);
// 开始
myCanvasToStram.start().then((canvasStream) => {
    //  这里我使用的是自己的peerConnection,你可以使用自己的webRtcPeerconnection
    let peerConnection = this.session.connection;
    const sender = peerConnection.getSenders().find((s) => s.track.kind === "video");
    sender.replaceTrack(canvasStream.getVideoTracks()[0]);
});
// 停止
myCanvasToStram.stop()

网站公告

今日签到

点亮在社区的每一天
去签到