默认关闭摄像头画面就是全黑,准备做一个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()