import { AliRtcPlugin, LocalStreamInfo } from 'aliyun-rtc-sdk';
export default class UserNamePlugin extends AliRtcPlugin {
private canvas: HTMLCanvasElement;
private requestId?: number;
// text 为希望绘制的人名
constructor(text: string) {
super('UserNamePlugin'); // 插件的名称,可自定义,须保证全局唯一
this.options = { text };
this.canvas = document.createElement('canvas');
}
isSupported(): boolean {
// 本插件不需要依赖特定版本 aliyun-rtc-sdk 的功能,所以直接返回 true 即可
return true;
}
setOptions(options: { text: string }): void {
// 用于动态更新希望绘制的人名
this.options = options;
}
shouldUpdate(): boolean {
// 当流发生改变的时候(比如开关摄像头),是否要调用 process 方法,这里我们直接返回 true
return true;
}
process(streamInfo: LocalStreamInfo): Promise<void> {
if (streamInfo.currentVideoTrack) {
// 如果有视频轨道,我们定义对视频轨道的处理方式
const videoTrack = streamInfo.currentVideoTrack as MediaStreamVideoTrack;
const settings = videoTrack.getSettings();
// 将画布的宽高调整为与视频流相同
this.canvas.width = settings.width!;
this.canvas.height = settings.height!;
// 将 MediaStreamTrack 转换为视频元素的源
const stream = new MediaStream([videoTrack]);
const videoElement = document.createElement('video');
videoElement.srcObject = stream;
videoElement.play();
const ctx = this.canvas.getContext('2d')!;
// 定时绘制视频帧到 canvas,并添加文字
const drawFrame = () => {
if (videoElement.readyState >= HTMLMediaElement.HAVE_CURRENT_DATA) {
ctx.drawImage(videoElement, 0, 0, this.canvas.width, this.canvas.height);
// 在右下角添加文字
ctx.fillStyle = 'white'; // 文字颜色
ctx.font = '40px Arial'; // 文字大小和字体
ctx.textAlign = 'right'; // 文本对齐
ctx.fillText(this.options.text, this.canvas.width - 20, this.canvas.height - 20); // 文本位置
}
this.requestId = requestAnimationFrame(drawFrame); // 持续绘制帧
}
this.requestId = requestAnimationFrame(drawFrame);
// 创建新的 MediaStream
const newStream = this.canvas.captureStream(settings.frameRate); // 或根据需要设置其他帧率
const newVideoTrack = newStream.getVideoTracks()[0];
// 调用 streamInfo.updateVideoTrack 替换视频流
streamInfo.updateVideoTrack(newVideoTrack);
} else if (this.requestId) {
// 如果之前设置了 requestAnimationFrame,且此时没有视频轨道,则取消绘制
cancelAnimationFrame(this.requestId);
}
return Promise.resolve();
}
}